Plugins
Kanun supports installable plugins so framework-specific or optional validation behavior can live outside the core package.
This keeps the base validator small while allowing packages to add new rules, messages, type inference, output transformations, request-context helpers, and framework adapters.
Installing A Plugin
Install the core package and the plugin you need:
npm install kanun @kanun-hq/plugin-filepnpm add kanun @kanun-hq/plugin-fileyarn add kanun @kanun-hq/plugin-fileRegister the plugin once during app startup:
import { Validator } from 'kanun';
import { fileValidatorPlugin } from '@kanun-hq/plugin-file';
Validator.use(fileValidatorPlugin);Available Plugins
- File Validation: upload validation rules, file size semantics, wildcard helpers, and Express/Fastify/Hono/h3 adapters.
- Phone Validation: phone number validation, parsed
PhoneNumberoutput, formatting helpers, and Arkormˣ-style casts.
Validator Context
Plugins can read extra runtime state through validator context.
const validator = Validator.make(data, rules).withContext({
request,
currentUser,
});Context is useful when a rule depends on request-bound information such as uploaded files, authenticated users, or framework services.
If you want to register request-scoped context once in middleware and let validators created later pick it up automatically, use the static API:
import { Validator } from 'kanun';
Validator.useContext({
request,
currentUser,
});Writing Your Own Plugin
Kanun exposes a plugin API for packages that need to register rules or extend runtime behavior.
import { definePlugin } from 'kanun';
export const examplePlugin = definePlugin({
name: 'example-plugin',
install: ({ registerRule, extendTranslations }) => {
registerRule('starts_with_kanun', (value) => {
return typeof value === 'string' && value.startsWith('kanun');
});
extendTranslations({
en: {
starts_with_kanun: 'The :attribute must start with kanun.',
},
});
},
});Add Rule Autocomplete For Plugin Users
If your plugin adds custom rules, you can augment Kanun's rule autocomplete so array-style rule definitions suggest your rule names in TypeScript.
declare module 'kanun' {
interface ValidationRuleAutocompleteMap {
starts_with_kanun: 'plain';
kanun_format: 'paramable';
}
}Use 'plain' for rules without parameters and 'paramable' for rules used like rule:value.
That makes plugin rules show up in array syntax such as:
const rules = {
name: ['required', 'starts_with_kanun', 'kanun_format:strict'],
};This only affects TypeScript autocomplete and typing. You still need to register the runtime rule implementation inside your plugin with registerRule(...).
If a plugin needs runtime state, document the expected shape of .withContext() and provide adapters when framework integration is common.