Your First Plugin
This tutorial creates a tiny plugin that writes dist/build-info.txt with a build timestamp.
Prerequisites
- An existing Shevky project
@shevky/baseavailable (installed as a dependency of@shevky/core)
1. Create the Plugin File
mkdir -p pluginsCreate plugins/build-info-plugin.js:
import { plugin } from "@shevky/base";
const hooks = {
[plugin.hooks.DIST_CLEAN]: async function (ctx) {
const target = ctx.path.combine(ctx.paths.dist, "build-info.txt");
const content = `Build timestamp: ${new Date().toISOString()}\n`;
await ctx.file.write(target, content);
ctx.log.info("[build-info] Created build-info.txt");
},
};
export default {
name: "build-info-plugin",
version: "0.0.1",
hooks,
};2. Register the Plugin in site.json
Add the plugin path to the plugins array:
"plugins": [
"./plugins/build-info-plugin.js"
]The plugin registry resolves relative paths from the project root.
3. Build and Verify
npm run build
cat dist/build-info.txtExpected Output
dist/build-info.txtexists.- File contains a line like:
Build timestamp: 2026-03-25T21:00:00.000Z
How It Works
- The build script loaded your plugin via
PluginRegistry.load(). - During the
dist:cleanhook, your handler was called with the plugin context. - You used
ctx.path.combine()andctx.file.write()from the base context. - The file was written to the
dist/directory.
Common Errors
| Error | Fix |
|---|---|
| Plugin not loaded | Check the path string in plugins[] - use relative path from project root |
| Module syntax errors | Ensure the file is valid ESM (use import/export, not require) |
| Missing output file | Verify the hook key is valid (plugin.hooks.DIST_CLEAN) |
Next Steps
- Try a different hook (e.g.,
content:ready) to accessctx.contentFiles. - Read the Plugin API Reference for all context fields.
- See the Plugin Cookbook for common patterns.