Registration Modifiers
Adapt a module per worker with .with() to strip features, redirect databases, and disclaim schema ownership.
The same module rarely runs identically in every worker. Registration modifiers adapt a module at the registration site. The module's code stays untouched; the worker composing it decides:
.with() calls merge, so modifiers can be layered.
Feature toggles
Nine boolean switches: orm, eventBus, graphql, queue, router, rpc, scheduled, middleware, webSocket. Each strips that feature's wiring for this registration:
queue: false: the module's queue processors aren't registered, so the worker passesbase checkwithout queue consumers in its wrangler config.graphql: false: the module's resolvers stay out of the schema.middleware: false: worth knowing specifically, because a module's global middleware otherwise runs on every request of the host worker.
Two semantics to internalize:
- Toggles control wiring, not the bundle. Stripped code is still imported and shipped; only its registration is skipped. If you need the code itself gone (bundle size, isolation), register a smaller module instead; see Composition Patterns.
- Toggles cascade into dependencies: a
{ module, when }entry naming a stripped feature is dropped with it.
externalSchema: Query-only tables
Registers the module's entities for queries but disclaims schema ownership: they're excluded from migration generation and schema sync in this worker. Use it when two workers share a database and the other one owns the tables: the owning worker registers the module normally and migrates, while this worker only reads and writes data.
The one-owner rule is enforced: check --all-workers (and every workspace deploy) compares ownership claims across workers by physical database identity (D1 database_id, PlanetScale host + database) and fails when two workers both claim the same table, since two owners means two migration histories writing DDL for one table. The fix it points to is this modifier (or externalEntities).
database: Route the module elsewhere
Routes the module to a named database in this worker (overriding the module's own orm.databaseName). It governs both where the module's entities register and where token-less @InjectRepository/@InjectDatabase in the module's declared member classes resolve, provided those classes declare their membership with @Injectable(NotesModuleKey). Boot validation enforces the declaration: a non-default-database module's class that injects token-lessly without declaring is rejected at startup, not discovered in production.
Commonly paired with externalSchema: true: this module's data lives in that other database, which somebody else migrates.
The composition mindset
A module states what it is; registrations state how each worker uses it. One Notes module can be, simultaneously: full-featured in the API worker, GraphQL-less in a webhook worker, and schema-external in a background worker sharing the database. That's the reuse story: one module, per-worker adaptation, no forks.