Create plugin
Generate the site-notes VitNode plugin with create-vitnode-app, see where it was registered, and open its first page and API endpoint.
A plugin is where a VitNode feature lives. Its pages, API, database tables, translations and AdminCP screens ship together as one package. In this lesson you generate site-notes, a small plugin for short announcements, and open the page and endpoint it starts with. The rest of the beginner path grows this same plugin.
Before you begin
- A running app from Setup, created with Turborepo (or as a Monorepo App). The plugin generator refuses to run without a
turbo.jsonat the workspace root.
Generate the plugin
From the workspace root, run the generator with --plugin and the name site-notes:
bun create vitnode-app@canary site-notes --pluginAnswer Yes to "Install dependencies?". The generator then installs and builds the plugin and reloads a running dev server. If you answered No, run pnpm install (or your manager's install), then restart pnpm dev.
The name becomes the package name, the plugin id, the first page's URL and the root key of its translations. Use a plain name. The generator drops a scope such as @acme/site-notes and refuses names core already serves, such as admin, api or users.
See what the generator changed
The generator printed one line per file it registered the plugin in:
+ Registered in apps/web/src/vitnode.api.config.ts
+ Registered in apps/web/src/vitnode.config.tssiteNotesPlugin() is now in the plugins array of vitnode.config.ts (pages, translations, AdminCP navigation) and siteNotesApiPlugin() in vitnode.api.config.ts (API routes, permissions, background work). The app's package.json gained "site-notes": "workspace:*". A Monorepo App gets the same lines for apps/api.
The new package, with the files the next lessons change:
src/config.api.tsdeclares the API half;src/config.tsxandsrc/routes.tsthe front-end half.src/api/builders.tsbinds the five API builders to the plugin, so API files never spell its id:buildModuleandbuildRoutefor modules and routes,buildQueueTaskfor queue tasks,defineCacheEntryfor cache entries anddefineEventfor events.- Every build writes
src/manifest.gen.tsandtypes/api-registry.gen.d.ts. Commit them; the second one is what types the plugin's own API calls (see API modules).
Check the result
Open http://localhost:3000/site-notes. The page says Hello from your plugin, and its card reads Your plugin's API answered: Hello from site-notes!. That text came from the plugin's API, which you can also call directly:
curl http://localhost:3000/api/site-notes/hello{ "message": "Hello from site-notes!" }
To check the plugin the way the app loads it, run the validator from the app folder:
pnpm vitnode plugin validate site-notesIt ends with 1 plugin valid. See Plugin commands for everything it checks.