Skip to content

The plugin system

Every tool in PocketArk is a plugin: one directory is one plugin, with frontend and backend side by side. plugin.json is the single source of truth.

plugins/<plugin-id>/
├── plugin.json # manifest (single source of truth; shared by both scanners)
├── README.md
├── frontend/ # frontend
│ ├── views/ # tool pages (one file per tools[] entry)
│ ├── settings/ # settings panel (optional)
│ ├── components/ # plugin-private components (optional)
│ ├── composables/ # composables (optional)
│ ├── schema.ts # database tables (optional, auto-aggregated)
│ ├── setup.ts # lifecycle hooks (optional, auto-scanned)
│ └── shared.ts # shared constants / helpers (optional)
└── backend/ # backend (optional)
├── mod.rs # Rust commands (#[tauri::command]) + `pub mod migrations;`
├── migrations.rs # migrations: exports `pub fn all() -> Vec<Migration>` (optional)
└── *.rs # other backend code / assets

Directories starting with _ or . are not registered (e.g. the _template).

Adding a plugin requires no registration in any framework file:

  • Frontend: Vite scans plugins/*/frontend/**views / settings / setup.ts / schema.ts are aggregated. Navigation, routing, titles, enable/disable toggles, the settings panel, the error boundary and KeepAlive all work automatically.
  • Backend: src-tauri/build.rs scans plugins/*/backend/mod.rs, parses its #[tauri::command] functions to register them, reads backend/migrations.rs to aggregate migrations, and generates the plugins/mod.rs include and the generate_handler! list.
ItemRule
Plugin idGlobally unique, kebab-case, equal to the directory name; route /tool/:id
Tool idtools[].id, globally unique; prefer <plugin-id> or <plugin-id>-<feature>
Rust commandFunction name = frontend call name, prefixed with <plugin_id>_
Migrationmigration(scope, version, ...) with scope = plugin id, version starting at 1 per scope
  • Plugin group order = the smallest order in the group.
  • Tool order within a group = order * 1000 + index in the tools array.
  • Default order is 100, then alphabetical by directory name.

Next: Create a plugin and the plugin.json manifest.