Skip to content

Convex API compatibility

The Convex API surface Nimbus supports today. Anything not listed as supported here should be assumed unsupported.

RegistrarStatus
querySupported
internalQuerySupported
mutationSupported
internalMutationSupported
actionSupported
internalActionSupported
httpActionSupported
paginatedQueryNimbus extension
internalPaginatedQueryNimbus extension
CapabilityQueryMutationAction / HTTP action
ctx.db readsYesYesNo
ctx.db writesNoYesNo
ctx.schedulerNoYesYes
ctx.runQuery / ctx.runMutation / ctx.runActionNoNoYes
ctx.authYesYesYes
SurfaceStatus
db.get(id)Supported
db.insert(table, value)Supported
db.patch(id, value)Supported
db.delete(id)Supported
db.replace(id, value)Not supported
db.systemNot supported
db.query(table)Supported
.withIndex(name, builder?) with eq, neq, gt, gte, lt, lteSupported
.filter(builder)Supported
.order("asc" | "desc")Supported
.take(n), .collect(), .first(), .unique()Supported
.paginate(paginationOpts)Supported
ValidatorStatus
v.any()Supported
v.null()Supported
v.string()Supported
v.number()Supported
v.boolean()Supported
v.id(table)Supported
v.literal(value)Supported
v.array(element)Supported
v.object(fields)Supported
v.optional(inner)Supported
v.union(...members)Supported
v.int64()Not supported
v.bytes()Not supported
v.record(keys, values)Not supported
v.float64()Not supported (use v.number())
  • defineSchema and defineTable(fields).index(name, fields) are supported. defineTable takes an object of field validators; a top-level union table definition is not supported.
  • The schema file is optional. A table without a schema accepts documents of any shape; adding a schema enforces the declared constraints.
  • The schema module must export default defineSchema(...).
  • Index fields must exist in the table definition, and index names must be unique per table.
  • System fields are _id, _creationTime, and _updateTime. _updateTime is a Nimbus addition.
  • ctx.scheduler.runAfter(delayMs, ref, args), ctx.scheduler.runAt(timestampMs, ref, args), and ctx.scheduler.cancel(jobId) are supported.
  • Only mutations can be scheduled.
  • Crons (cronJobs from convex/server) are not supported.
  • Routes are read from convex/http.ts only, which must export default a router initialized with httpRouter().
  • Each route declares exactly one of path or pathPrefix; both forms must start with /.
  • Routes are served under {deploymentUrl}/http/{path}.
ProviderShape
OIDC{ domain, applicationID }
Custom JWT{ type: "customJwt", issuer, jwks, algorithm } with optional applicationID
  • Provider config lives in convex/auth.config.ts or .js (exactly one).
  • OIDC metadata is discovered at {issuer}/.well-known/openid-configuration.
  • An OIDC token’s aud must equal the provider’s applicationID; multi-audience tokens are rejected.
  • Custom JWT algorithms are limited to RS256 and ES256.
  • ctx.auth.getUserIdentity() is supported; identities carry tokenIdentifier in the form issuer|subject. Nimbus additionally exposes ctx.auth.getVerifiedIdentity().

The convex npm package Nimbus provisions exposes convex/react, convex/browser, convex/server, and convex/values.

ExportStatus
ConvexProvider, ConvexProviderWithAuthSupported
ConvexReactClientSupported
useQuery, useMutation, useAction, useQueriesSupported
useConvex, useConvexAuth, useConvexConnectionStateSupported
usePaginatedQuerySupported for functions registered with paginatedQuery
ConvexHttpClient, ConvexClient (browser)Supported
paginationOptsValidatorSupported
ConvexErrorNot exported

WebSocket clients reconnect automatically and serve reactive query subscriptions.

Each tenant’s deployment URL is {host}/convex/{tenantId}. Under it:

PathPurpose
POST /queryRun a query
POST /query/paginatedRun a paginated query
POST /mutationRun a mutation
POST /actionRun an action
/http/{path}HTTP actions
POST /schedule/run_after, POST /schedule/run_atSchedule a mutation
DELETE /schedule/{jobId}Cancel a scheduled job
/wsWebSocket subscriptions

For authenticated requests, {tenantId} selects the trusted verifier installed for that silo before the bearer is inspected. A token accepted for one silo is not reusable against another silo unless that second silo is deliberately bound to a verifier that also accepts it. An unprovisioned silo fails with 401; Nimbus does not fall back to a process-wide Convex verifier.

  • "use node" modules are supported and may contain only actions.
  • The Node version is set by convex.json node.nodeVersion: "20", "22", "24", or "26" (default "24").
  • External packages are declared in convex.json node.externalPackages — an explicit list, or ["*"] alone.
  • Node builtin imports are accepted in both bare and node: forms; fs and node:fs resolve identically.
  • "use bun" modules fail closed unless a Bun runtime adapter is linked into the server build.

Directive-free modules run on the default V8 runtime, which reproduces Convex’s deterministic time and randomness rules. See the two Convex runtimes for the full explanation.

SurfaceBehavior
Math.random()Seeded PRNG. Deploy-stable at module load; re-seeded with fresh entropy per query / paginated query / mutation.
Date.now(), new Date()Deploy timestamp at module load; frozen at invocation start through a query / paginated query / mutation; live (coarsened) host clock in actions.
performance.now()Fixed during import and queries; increments in mutations and actions.
performance.timeOriginPinned to the deployment timestamp for every invocation kind.
fetchActions only. Queries and mutations fail closed with a parity error; actions remain subject to the tenant egress policy.
process.envPresent and capability-gated. No other process fields (versions, release, cwd, Buffer).
node:async_hooksAsyncLocalStorage and AsyncResource only (no createHook / executionAsyncId). A store does not propagate into ctx.runQuery / ctx.runMutation / ctx.runAction.
WebAssemblyinstantiate / Module / Instance available; shared WebAssembly.Memory is disabled.
Web globalsWebSocket, URL, structuredClone, and timers are present — a superset of Convex’s documented default-runtime globals.

The deployment timestamp is derived from the deployed bundle entrypoint’s modification time (a proxy — copies that alter the mtime shift it). Determinism here is behavioral parity, not a security boundary.

  • File storage: ctx.storage and the _storage system table.
  • Search: full-text (withSearchIndex) and vector search.
  • Crons: cronJobs from convex/server.
  • db.replace and db.system.
  • Validators v.int64(), v.bytes(), v.record(), v.float64().
  • The ConvexError export.