React + Vite plugin development tutorial
For real plugins with a UI, use project-based development with React 19 + Vite 7 + TypeScript + Tailwind, together with the launcher’s built-in component library@qomicex/plugin-ui. Compared with hand-written plain HTML, you get component reuse, type checking, HMR, and on-demand packaging.
Generate the project with the qomicex create scaffold (Scaffold) (it configures everything for you). This tutorial explains what the scaffold produces and what each config does, so you can adjust as needed.
1. Why Vite
- Type safety: TS strict mode;
tsc --noEmitcatches errors before the build - Component reuse: Use the same
@qomicex/plugin-uicomponents as the launcher (Card / Button / Dialog / Select, and more); styles follow the theme automatically - Clean output: Only the components you use are bundled, and CSS is generated on demand (Tree-shaking + Tailwind JIT)
2. Generate a project with the CLI (recommended)
@qomicex/plugin-ui, with the id already substituted in manifest.json/package.json):
qomicex create (packages/qomicex-cli/templates/). Add or remove from it when it does not fit your needs.
Manual setup without the CLI (alternative)
@qomicex/plugin-ui is a workspace package inside the launcher repository, so referencing it with file:../../packages/plugin-ui is enough. You do not need to publish it to npm.
package.json
vite.config.ts: the key is a relative base
tailwind.config.js: reference the preset
content only scans ./src by default. The style classes of @qomicex/plugin-ui components (bg-card, bg-muted, text-foreground) live in the component source, not under your src. If you do not add ../../packages/plugin-ui/src/**/*.{ts,tsx} to content, the built CSS is missing those classes and the plugin page has no styling (a built CSS file of only a few KB is the typical symptom).
postcss.config.js
tsconfig.json
src/index.css
3. Typed wrapper for the plugin API
Plugin scripts talk to the launcher throughwindow.__PLUGIN_API__. Wrap it in a typed module, and handle the case where there is no API bridge when you run npm run dev standalone (opening the page directly in a browser):
src/api.ts:
4. Write the plugin page
src/main.tsx:
./App.tsx, ./api.ts). Vite’s path resolution has a bug and fails when the extension is omitted. allowImportingTsExtensions is already enabled in tsconfig.
Using the component library in src/App.tsx:
@qomicex/plugin-ui exports: Button / Badge / Card(Header/Title/Description/Content/Footer) / Checkbox / Combobox / Dialog / Input / Label / Select(+SelectOption/SelectDivider) / Separator / Table / Tabs / Textarea / Tooltip / useMessageBox(+MessageBoxProvider) / Icon / Glyph / ICON_NAMES / hasIcon / cn. Icons also have per-icon subpaths at @qomicex/plugin-ui/icons/<name> (see Icons). See plugin-ui component library for full usage.
5. Overlay window and theme files
overlay.html and theme.css are not part of the Vite build output, so you must copy them into dist/ manually when packaging:
overlay.html→dist/overlay.html(where manifestcontributes.overlay.filepoints)theme.css→dist/theme.css(where manifestentry.themepoints)
__PLUGIN_API__ bridge script at the end of the page <body>. So do not capture window.__PLUGIN_API__ synchronously while the page loads (the bridge is not injected yet). Read it lazily inside event callbacks:
6. Package the .qplugin
Package with the CLI (recommended)
qomicex pack handles everything automatically: it builds the frontend, copies the root overlay.html / theme.css into dist/, and assembles the zip (manifest.json at the root plus dist/**). If entry.theme or contributes.overlay.file reference files under dist/ while the source sits in the root directory, they are copied in automatically.
Manual packaging without the CLI (alternative)
Packaging script (scripts/build.sh)
Package structure after packaging
plugins/{id}/{path}, so entry.frontend: "dist/index.html" fetches plugins/{id}/dist/index.html. The dist/ subdirectory must stay inside the zip: if you hoist the files from dist to the zip root, then after installation dist/index.html, dist/theme.css, and dist/overlay.html all return 404 (blank page, no styles, overlay window will not open).
7. Install and test
- Run
qomicex pack(or manuallybash scripts/build.sh 0.1.0; on Windows:pwsh ./scripts/build.ps1 0.1.0) - Launcher → Plugins → upload
release/my-plugin-0.1.0.qplugin - Enable the plugin → restart the launcher → open the plugin page from the sidebar
qomicex dev with the debug harness is preferable: hot reload in the browser, no Tauri or backend needed (see Debugging and hot reload).
FAQ
Next steps
- Full API reference: Complete plugin API reference
- Component library: UI component library (.p-* styles)
- Overlay window: Overlay window development
- CLI command reference: CLI reference
- Debugging and hot reload: Debugging and hot reload
- Publishing guidelines: Publishing guidelines