NotusBase

NotusBase modules

These modules came before NotusBase ran Convex components from npm (app.use, since 2026-11-11). They ship inside the binary, so they follow the NotusBase version, with no npm package. They only enter a project that enables them.

In 0.3 the modules that a component from npm does the same as left the binary: ratelimit (use @convex-dev/rate-limiter), stripe (@convex-dev/stripe) and migrations (@convex-dev/migrations). An import of one stops codegen and deploy naming the package. What stays is what has no component that does the same: email sends through queue, and certificates is a library of NotusBase's own.

ModuleWhat it doesCame from
queueQueue with a parallelism limit, retries with growing backoff and a notification on completion@convex-dev/workpool, @convex-dev/action-retrier
emailTransactional email written in the mutation's transaction and sent through the queue, by the panel's SMTP or Resend; under notusbase dev it is captured in the table. Templates with typed variables, a shared layout and a preview in the panelthe idea of @convex-dev/resend (no code)
certificatesClient certificate (A1) for banks and government APIs: fetch with mutual TLS and XML signatures. A library: no tables, no functionsOriginal

Enabling

Three steps, all in the project. The example uses a module x:

  1. Tables in convex/schema.ts, all with the module's prefix:

    import { xTables } from "notusbase-modules/x/schema";
    export default defineSchema({ ...xTables, /* yours */ });
  2. A file convex/x.ts, named after the module:

    export * from "notusbase-modules/x";

    The module calls its own functions through that path (x:name), so the file cannot have another name or live in a subfolder.

  3. The route in convex/http.ts, if the module has one.

Then notusbase deploy or notusbase dev. A module that is not enabled does not enter the bundle or create a table.

Disabling

Remove the file from convex/, the tables from schema.ts and the route, and publish. The code leaves the bundle and the data stays in the database, because NotusBase never drops a table. Enabling it again finds everything as it was.

How it works

Creating a module

A folder modules/<name> with index.ts (functions and client), schema.ts (<name>Tables), README.md and, if it reuses code from another project, NOTICE with license and attribution. A module that reads process.env or needs another module says so in module.json, next to the code: { "env": { "required": [], "production": [], "when": { "NAME=value": [] }, "optional": [] }, "requires": [] }. production is required except under notusbase dev, and when only while the server has that value. The deploy, the start and the Environment screen warn from it, and needs_test.go checks it against the code. The test lives in app/modules/<name>, with a real project, and goes into the bench/smoke.sh list. A library without tables or functions, such as certificates, has no schema.ts, and its test can be a Go test that deploys a small project.