Function types
| Constructor | Description |
|---|---|
FunctionSpec.publicQuery | Public query function |
FunctionSpec.publicMutation | Public mutation function |
FunctionSpec.publicAction | Public action function |
FunctionSpec.internalQuery | Internal query function |
FunctionSpec.internalMutation | Internal mutation function |
FunctionSpec.internalAction | Internal action function |
Defining a spec
Each function spec defines the function’s name, arguments schema, and returns schema. Theargs, returns, and (optional) error schemas are passed as () => Schema callbacks, evaluated lazily the first time the function is invoked. Function specs are added to a GroupSpec and default-exported from a *.spec.ts file. See The Spec/Impl Model for a full walkthrough.
confect/notes.spec.ts
confect codegen after adding or changing specs.
Typed errors
A spec can also declare an optionalerror schema. When it does, the corresponding handler’s Effect error channel is typed as that schema, and the failure is decoded for callers at every call site (React hooks, JS clients, and tests). See Error Handling for the full walkthrough.
Implementing functions
Each function impl contains a handler that implements the function’s logic. Function impls are composed into group impls using Effect layers. The handler receives the decoded arguments as its first parameter and returns anEffect. Use the generated services (like DatabaseReader, DatabaseWriter, Auth, etc.) inside your handler to interact with Convex.
confect/notes.impl.ts
GroupImpl.finalize is the per-group completeness check: it only typechecks once every function declared by the spec has been provided to the group layer.
Convex bundles a deployment into a single artifact, but a function’s cold
start only evaluates the module graph reachable from its entry point. Confect
emits one Convex module per group, so cold-starting a function only evaluates
its own group’s spec, impl, and the tables it touches. To keep that cold start
fast, import Effect from its submodule paths (
import * as Schema from "effect/Schema") rather than the effect barrel in your confect/ files—a
barrel import pulls the whole Schema namespace into the module graph your
function evaluates at cold start, even when you use only a small part of it.