Plugins
Plugins#
Otok ships a typed plugin API for official extensions and app-specific integrations. Plugins are optional — existing composition packages and manual createOtokApp({ configure }) wiring continue to work.
Quick start#
pnpm otok add hello
Or manually in otok.config.ts:
// otok.config.ts
import { defineConfig } from "@kamod-ch/otok";
import hello from "@kamod-ch/otok-plugin-hello";
export default defineConfig({
plugins: [hello()],
});
Wire resolved runtime config in src/server.ts:
import { createOtokApp, readOtokManifest } from "@kamod-ch/otok/server";
import { loadOtokResolvedConfig } from "virtual:otok-config";
import { routes, notFoundRoute, errorRoute } from "virtual:otok-routes";
const { runtime, applyAppPlugins } = await loadOtokResolvedConfig();
export default createOtokApp({
routes,
notFoundRoute,
errorRoute,
...runtime,
manifest: readOtokManifest(import.meta.url),
configure: (app) => {
void applyAppPlugins(app);
},
});
Apps without otok.config.ts keep working. virtual:otok-config resolves to an empty config.
Hook order#
Plugins run in declared order:
- Option validation (
schema) configconfigResolvedconfigureViteconfigureServer(dev)buildStart/buildEndconfigureApp(runtime)
buildEnd runs in reverse order.
Public vs internal API#
| Public | Internal |
|---|---|
defineConfig, definePlugin |
PluginContainer internals |
OtokPlugin, OtokUserConfig |
config file bundling |
virtual:otok-config |
generated temp config bundles |
virtual:otok-plugin/<name>/<id> |
devtools metadata (reserved) |
Packages#
| Package | Purpose |
|---|---|
@kamod-ch/otok-config |
Plugin contract and resolution |
@kamod-ch/otok-plugin-hello |
Minimal example plugin |
@kamod-ch/otok-plugin-fixture |
Test fixture plugin |
See also Create your first Otok plugin, CLI — otok add, and Composition Packages.