Tutorial: Hello World Plugin
Build a simple panel plugin that displays "Hello World" and registers a tool for the AI assistant.
What you'll build
- A sidebar panel that displays a greeting
- An LLM tool called
sayHellothat the AI can use
Prerequisites
- Node.js 18+
- pnpm (recommended) or npm
- Basic React knowledge
Step 1: Create the project
Create a new folder for your plugin:
mkdir hello-world-plugin
cd hello-world-plugin
Initialize the project:
pnpm init
Install dependencies:
pnpm add @practicalkit/plugin-sdk react react-dom
pnpm add -D typescript vite @vitejs/plugin-react @types/react @types/react-dom
Step 2: Create the manifest
Create manifest.json in your project root:
{
"id": "hello-world-plugin",
"name": "Hello World Plugin",
"modules": [
{
"id": "hello-panel",
"name": "Hello World",
"main": "index.html",
"type": "panel"
}
]
}
Key fields:
id- Unique identifier for your plugin (use lowercase with hyphens)name- Human-readable name shown in the UImodules- Array of modules your plugin providesmodules[].type- Usepanelfor sidebar panels
Step 3: Create the HTML entry point
Create index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hello World Plugin</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Step 4: Configure TypeScript
Create tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true
},
"include": ["src"]
}
Step 5: Configure Vite
Create vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
build: {
outDir: "dist",
rollupOptions: {
input: "index.html",
},
},
});
Step 6: Create the SDK instance
Create src/sdk.ts:
import { PracticalKitSdk } from "@practicalkit/plugin-sdk";
// Create a single SDK instance for the entire plugin
export const sdk = new PracticalKitSdk();
// Initialize the SDK (connects to the host application)
sdk.init();
Single Instance
Always create one SDK instance and export it. Multiple instances will cause issues.
Step 7: Create the React app
Create src/main.tsx:
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Create src/App.tsx:
import { useEffect, useState } from "react";
import { sdk } from "./sdk";
export default function App() {
const [greeting, setGreeting] = useState("Hello, World!");
useEffect(() => {
// Register an LLM tool when the component mounts
sdk.llm.registerTool({
name: "sayHello",
description:
"Greets someone by name. Use this when the user asks you to say hello to someone.",
parameters: {
type: "object",
properties: {
name: {
type: "string",
description: "The name of the person to greet",
},
},
required: ["name"],
},
handler: async (args) => {
const { name } = args as { name: string };
const message = `Hello, ${name}!`;
// Update the UI
setGreeting(message);
// Return the result to the LLM
return message;
},
});
sdk.logs.info("Hello World plugin loaded");
// Cleanup: unregister the tool when unmounting
return () => {
sdk.llm.unregisterTool("sayHello");
};
}, []);
return (
<div style={{ padding: "16px" }}>
<h1>{greeting}</h1>
<p>Ask the AI to say hello to someone!</p>
</div>
);
}
Step 8: Add build scripts
Update your package.json:
{
"name": "hello-world-plugin",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build && cp manifest.json dist/"
}
}
Step 9: Build the plugin
pnpm build
This creates a dist/ folder with your bundled plugin and manifest.
Step 10: Install in PracticalKit
- Open PracticalKit
- Go to Plugins > Add Plugin...
- Navigate to your plugin's
dist/folder - Select
manifest.json - Restart PracticalKit when prompted
Your "Hello World" panel should now appear in the sidebar!
Try it out
- Click on the Hello World panel in the sidebar
- Open the chat and ask: "Say hello to Alice"
- The AI will use your
sayHellotool - Watch the panel update with the greeting!
Next steps
- SDK Reference - Explore all available APIs
- Plugin Manifest - Learn about permissions and module types