confect/tables/: one file per table, each default-exporting a Table.make(...) value. The filename is the table name — confect/tables/notes.ts defines a table called notes — so filenames must be valid JS identifiers and may not start with _ (Convex reserves underscore-prefixed names for system tables). Codegen scans this directory and produces confect/_generated/schema.ts (the runtime DatabaseSchema, consumed by your impls), confect/_generated/convexSchema.ts (the deploy-time Convex SchemaDefinition re-exported from convex/schema.ts), and a pair of consumer-facing modules per table: confect/_generated/id.ts (a type-safe Id constructor) and confect/_generated/tables/<name>.ts (a thin wrapper that binds the table name). You never edit any of these generated files directly.
Each table is defined with Table.make, which takes a callback returning the table’s fields. The callback runs lazily — only the first time the table’s Fields, Doc, or tableDefinition is accessed — so a function that never touches a table pays no schema-construction cost for it at cold start. Indexes are defined on tables the same way as in the base Convex APIs. Cross-table Id references are constructed with the codegen-emitted Id helper from confect/_generated/id.ts, whose argument is type-constrained to the set of declared table names.
confect/tables/notes.ts
confect/tables/users.ts
confect/tables/*.ts file must default-export a Table — codegen reads module.default and applies the filename as the table name. Consumers (specs, impls, HTTP handlers, etc.) reach a table’s derived Schemas through the generated wrapper at confect/_generated/tables/<name>, e.g. import notes from "../_generated/tables/notes" and then notes.Doc.
Deriving table Schemas
Fields
ATable’s Fields property contains an Effect Schema for the user-defined fields of a table.
Doc
ATable’s Doc property contains an Effect Schema for the table’s document, meaning the table’s user-defined Fields plus its system fields (_id and _creationTime).