Creating Plugins
Step-by-step guide to building an OmniSvelte plugin — from setup to CLI command registration.
Creating Plugins
Plugins can integrate with and extend any part of the framework — database tables, auth providers, SvelteKit hooks, CLI commands, Vite plugins, realtime channels, email templates, and more.
Minimal plugin
ts
// plugins/my-plugin.ts
import type { OmniPlugin } from 'omni-svelte/plugins';
export function myPlugin(options: { apiKey: string }): OmniPlugin {
return {
name: 'my-plugin',
version: '1.0.0',
async onSetup(ctx) {
ctx.logger.info(`my-plugin: initialized with key=${options.apiKey.slice(0, 4)}...`);
}
};
}Register in svelte.config.js:
js
import { myPlugin } from './plugins/my-plugin.js';
const config = {
omni: {
plugins: [myPlugin({ apiKey: process.env.MY_API_KEY })]
}
};Adding database tables
ts
import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';
export function auditPlugin(): OmniPlugin {
const auditLogs = pgTable('audit_logs', {
id: serial('id').primaryKey(),
action: text('action').notNull(),
modelName: text('model_name').notNull(),
recordId: text('record_id').notNull(),
createdAt: timestamp('created_at').defaultNow()
});
return {
name: 'audit',
registerTables: () => ({ auditLogs }),
onModelEvent: async ({ type, modelName, data }) => {
if (['created', 'updated', 'deleted'].includes(type)) {
await db.insert(auditLogs).values({
action: type,
modelName,
recordId: String(data.id)
});
}
}
};
}Adding CLI commands
ts
export function myPlugin(): OmniPlugin {
return {
name: 'my-plugin',
registerCommands: () => [
{
name: 'init',
description: 'Initialise my-plugin resources',
run: async (args, flags) => {
console.log('Initialising my-plugin...');
// async setup logic
}
},
{
name: 'status',
description: 'Show my-plugin status',
run: async () => {
console.log('my-plugin: OK');
}
}
]
};
}Users run: omni my-plugin:init, omni my-plugin:status
Extending SvelteKit hooks
ts
export function requestLogPlugin(): OmniPlugin {
return {
name: 'request-log',
handle: async ({ event, resolve }) => {
const start = Date.now();
const response = await resolve(event);
const duration = Date.now() - start;
console.log(`${event.request.method} ${event.url.pathname} → ${response.status} (${duration}ms)`);
return response;
}
};
}Adding a Vite plugin
ts
export function myPlugin(): OmniPlugin {
return {
name: 'my-plugin',
vitePlugins: [
{
name: 'my-plugin-vite',
resolveId(id) {
if (id === '$my-plugin') return '