Skip to content
DocsPlugin development

Context and services

Use the services provided to your plugin's register function.

Context overview

The loader creates a context for each installed plugin and passes it to register(ctx).

PropertyPurpose
name, versionInstalled package identity
dbShared Drizzle database instance
coreSchemaSelected core table definitions
id(prefix)Generate an ID using the kernel helper
hooks.on()Subscribe to lifecycle events
settingsRead and write settings
audit.log()Record audit data
jobsEnqueue jobs and inspect queued work
storageInvoice/media upload and download helpers
scheduler.every()Register an in-process periodic task
loggerPlugin-prefixed debug, info, warning, and error logging
errorsHTTP error helpers
authPassword hashing and verification helpers
inventoryInventory service helpers
csvCSV parsing and serialization

Read settings and log an event

js
const label = (await ctx.settings.get('hello.label')) ?? 'Hello'
ctx.logger.info('Plugin registered', { label, version: ctx.version })

Namespace your keys explicitly. The shared settings service does not automatically prepend your package name.

Schedule periodic work

js
ctx.scheduler.every(60_000, async () => {
  ctx.logger.debug('Periodic task running')
}, { label: 'heartbeat' })

The scheduler manages intervals and clears them when the plugin is unloaded. It logs exceptions from individual ticks. Work can overlap if a callback takes longer than the interval; coordinate long-running or non-repeatable operations accordingly.

For durable tasks, ctx.jobs.enqueue(type, payload, options) uses the core job queue. A corresponding job handler must be registered by the runtime integration. The context does not expose a method for registering arbitrary handler types.

Database and storage

ctx.db is the shared database instance, not an automatically tenant-filtered or plugin-schema-scoped client. Use explicit table/schema definitions and preserve tenant ownership in queries.

Storage helpers derive their tenant context from the installed plugin record. The context provides uploadInvoicePdf, uploadMedia, and getPresignedDownloadUrl.

Current limitations

ctx.inventory.getStock() is currently a stub that returns 0; it must not be used as an actual stock reading. The factory provides inventory.move and inventory.defaultWarehouseId separately.

There is no Fastify instance, HTTP route registrar, or UI extension registrar on the current context. Plan those integrations against explicit runtime support rather than adding undeclared context methods.

Source reviewed Checked against kernel fe5c475.

Found something unclear? Let us know

Start exploring

NavigateOpenEscClose