Skip to main content

kickjs-add-plugin

Use when scaffolding a feature that bundles modules + DI + middleware + adapters together (auth, monitoring suite, multi-tenant scaffolding).

Source facts

Repository
forinda/kickjs-examples-archive
Last source activity
October 16, 2026 at 00:14
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
kickjs-add-plugin
description
Use when scaffolding a feature that bundles modules + DI + middleware + adapters together (auth, monitoring suite, multi-tenant scaffolding).
<!-- Generated by `kick g agents` for settings-api. Edits are overwritten on the next refresh; keep customisation in a SKILL.local.md alongside. --> **When plugin > adapter**: a plugin is the right answer when the integration ships **more than one** of: a module, a DI binding, middleware, or another adapter. If you have a single hook (`beforeStart`) and no other contributions, use `defineAdapter` instead. **Canonical shape**: ```ts import { definePlugin } from '@forinda/kickjs' export const AuthPlugin = definePlugin({ name: 'AuthPlugin', defaults: { tokenTtl: '1h' }, build: (config, { name }) => ({ modules: () => [AuthModule()], adapters: () => [JwtAdapter({ ttl: config.tokenTtl })], middleware: () => [requestIdMiddleware()], register(container) { container.registerFactory(TOKEN_SIGNER, () => createSigner(config)) }, contributors() { return [LoadCurrentUser.registration] }, onReady({ server }) { log.info(`AuthPlugin listening on port ${server.address().port}`) }, }), }) // In bootstrap: bootstrap({ plugins: [AuthPlugin({ tokenTtl: env.TOKEN_TTL })] }) // <-- parens ``` **Inline plugin literal** — the canonical answer for one-off DI bindings. There's no top-level `register:` on `bootstrap` itself: ```ts bootstrap({ plugins: [{ name: 'vector-store', register(c) { c.registerInstance(VECTOR_STORE, store) } }], }) ``` **Execution order** (memorize): plugin `register()` → plugin `middleware()` → plugin `modules()` + user modules → plugin `adapters()` + user adapters → server listens → plugin `onReady()`. **Static vs dynamic modules**: `modules()` returning an array is introspectable (Swagger, DevTools see it). `setup(registry)` is imperative — pick the latter when the module set depends on resolved config. **Multi-instance** — `.scoped('users', { url })`; derive unique DI tokens from `ctx.name` inside `build`: ```ts build: (config, { name }) => ({ register(c) { c.registerInstance(createToken(`cache/${name}`), client) }, }) ``` **Precedence**: plugin contributors land at `'adapter'` precedence — beat global, lose to module/class/method same-key. **Red flags**: - `bootstrap({ plugins: [AuthPlugin] })` — passed factory. Call it: `AuthPlugin()`. - Reaching for a plugin when an adapter would do (no modules, no DI bindings, no contributors) — overkill; use `defineAdapter()`. - `.async()` plugin that depends on `modules()` / `middleware()` / `adapters()` / `contributors()` — those are dropped. `.async()` only resolves `register()` + `onReady()`. - Confusing CLI plugins (`defineCliPlugin` from `@forinda/kickjs-cli`) with runtime plugins (`definePlugin` from `@forinda/kickjs`) — different surfaces, different registration sites. - `dependsOn: ['SomePlugin']` referring to a plugin not in the boot list — throws `MissingMountDepError` at boot. **Nuances**: - `definition` is `Object.freeze`'d metadata; useful for version checks (`compare(AuthPlugin.definition.version, '1.2.0')`) — not mountable.
View on GitHub