Skip to main content
Use this guide when a runtime capability needs a reusable contract and lifecycle. Keep the extension focused on one capability boundary. Use Extensions when you only need to enable an existing extension.

Prerequisites

  • A Veryfront project that imports veryfront/extensions.
  • A concrete capability gap to fill.
  • deno available on your PATH.

Scaffold an extension

This creates a local package:
Validate the extension shape:
For first-party extensions in the Veryfront monorepo, use an ext- directory prefix. The capability and contract audit tasks only check extension directories with that prefix. Local downstream extensions do not need it.

Write the factory

Provide a contract

Use provides when the implementation does not need async setup:
Use setup(ctx) when the implementation opens resources or registers contracts after async initialization.

Declare capabilities

Capabilities document runtime needs. Use a recognized type and matching scope field so Veryfront can map the capability to a Deno permission flag and audit it in CI.
Common capability types: For first-party extensions, mirror the same capabilities array in deno.json under veryfront.capabilities.

Understand load order

Veryfront loads extensions in this order:
Providers load before consumers. setup() runs in sorted order. teardown() runs in reverse order during shutdown or reload. Use presets to group extensions that load together:
During development, changes to veryfront.config.ts trigger teardown, rediscovery, and setup. Release resources in teardown() so reloads do not leak connections, timers, or file handles.

Test the extension

Test the factory first:
Then test the contract through the extension loader:
Run the tests:

Package the extension

Package an extension only when it needs reuse across projects.
  1. Export the extension factory as the default export.
  2. Set veryfront.extension: true in deno.json or package.json.
  3. Declare capabilities in package metadata and in the factory.
  4. Declare contract metadata through contracts or static provides.
  5. Include tests for the factory and contract implementation.
  6. Publish to npm or JSR.
Users install the package and Veryfront discovers it:
Use semver for releases. Treat contract shape changes as breaking changes.

Verify it worked

  1. Run veryfront extension validate extensions/my-cache.
  2. Run deno test --no-check --allow-all extensions/my-cache/src/.
  3. Add the factory to veryfront.config.ts and restart veryfront dev.
  4. Confirm the dev log lists the extension under its declared name.
  5. Resolve the contract from app code and confirm it uses the extension’s implementation.

Next