Convex Database Bootstrap
Productivity
What it does
Initializes a Convex real-time database project from scratch with schema, queries, mutations, and environment wiring. Follows Convex conventions so the project works correctly with real-time subscriptions out of the box.
The pattern
Workflow (6 steps):
-
Confirm mode. Is this a new project or adding Convex to an existing one? New projects get a fresh
convex/directory. Existing projects get Convex files appended without overwriting anything. -
Bootstrap. Initialize the Convex project: install the npm package, run
npx convex devto create the project and generate the deployment URL. Store the URL in.env.local. -
Define schema. Create
convex/schema.tswith domain tables. Each table gets:- Field definitions using Convex validators (
v.string(),v.number(),v.optional()) - Indexes for common query patterns (always index fields you filter or sort by)
- A
_creationTimefield is automatically included
- Field definitions using Convex validators (
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
tasks: defineTable({
title: v.string(),
status: v.union(v.literal("pending"), v.literal("done")),
assignee: v.optional(v.id("users")),
}).index("by_status", ["status"])
.index("by_assignee", ["assignee"]),
});
-
Scaffold functions. Create query, mutation, and action files following Convex's three-function-type separation:
- Queries read data. They are cached and reactive (subscribers get automatic updates).
- Mutations write data. They are transactional and trigger reactive updates.
- Actions call external APIs or do non-deterministic work. They cannot directly read or write the database (call mutations from actions for writes).
-
Wire environment. Set environment variables via the Convex dashboard or
npx convex env set KEY VALUE. Common variables: API keys for actions, webhook secrets, feature flags. -
Deploy and smoke test. Push the schema with
npx convex dev(development) ornpx convex deploy(production). Verify by running a mutation, then a query, and confirming the data round-trips.
Non-destructive by design. The bootstrap process appends missing configuration. It checks for existing convex/ directories, existing schema files, and existing function files before writing anything. If files exist, it reports what it found and asks how to proceed.
Key decisions
Validators in schema, not at runtime. Convex schemas enforce types at write time. If a mutation tries to insert invalid data, it fails immediately. This eliminates bugs where bad data enters the database and causes errors downstream.
Query/mutation/action separation is non-negotiable. Queries are pure reads (cached, reactive). Mutations are pure writes (transactional). Actions are side-effectful (external API calls). Mixing concerns produces functions that Convex cannot optimize.
Index everything you query by. Convex rejects queries that require full table scans at scale. Define indexes at schema time, not as an afterthought.
When to use it
When starting a new project that needs real-time data (collaborative apps, dashboards, chat, live feeds). When adding a real-time backend to an existing React or Next.js application. When you want a database that handles subscriptions natively instead of bolting on WebSocket layers. Not the right choice for projects that need raw SQL, complex joins, or traditional relational modeling.