Announcing Convex 0.1.3
Schemas are here!
This release has some big changes to Convex that we’re really excited to show to you all. Two of these are breaking changes that will require you to make minor updates to your app, so read carefully:
- Schema Support
- Breaking: Generated Code Changes
- Breaking:
db.updaterenamed todb.patch - TypeScript Type Checking
- Extra Goodies
As always, let us know what you think of this in the Convex Slack Community!
Schema Support
The biggest feature in this update is schemas. Convex now supports defining the schema of your project in a schema.ts file. The schema file describes the tables in your Convex app and the type of documents stored in each table. It might look something like:
import { defineSchema, defineTable, s } from "convex-dev/schema";
export default defineSchema({
messages: defineTable({
body: s.string(),
time: s.number(),
user: s.id(),
}),
users: defineTable({
name: s.string(),
}),
});
Once you define a schema, if you rerun npx convex codegen, Convex will use that schema to generate two new generated files: dataModel.ts and server.ts.
The Document type from dataModel.ts provides document types for all of your tables. You can use these both when writing Convex functions and in your React components:
import { Document } from "../convex/_generated/dataModel";
function MessageView(props: { message: Document<"messages"> }) {
...
}
The query and mutation functions in server.ts have the same API as before but now provide a db with more precise types. Functions like db.insert(table, document) now understand your schema. Additionally database queries will now return the correct document type (not any).
A couple of notes about schemas:
- This is currently a “types only” feature. Adding a schema will give you precise, code generated types, but won't completely prevent you from writing bad data into your tables. Convex will support schema enforcement at runtime in the future.
- There are still some APIs like
db.get(id)that still use loose types likeanyeven if you define a schema. We’ll be fixing this soon too!
Lastly, schemas are optional! We encourage you to start your project schema-less while you’re prototyping and add a schema once you've solidified your plan.
To learn more about schemas, see the documentation at https://docs.convex.dev/using/schemas!
Breaking: Generated Code Changes
We’ve made a couple of changes to our generated code:
- The location of our generated React hooks has moved from
convex/_generated.tstoconvex/_generated/react.ts. - The
queryandmutationwrappers have moved from our npm package atconvex-dev/serverinto generated code atconvex/_generated/server.ts. - There is a new generated file:
convex/_generated/dataModel.ts.
Rationale
We’ve added the new generated server.ts and dataModel.ts to give you schema-specific type safety. You can read more about that in “Schema Support” above. We also generate server.ts and dataModel.ts even before you define a schema so that you won’t need to change your imports when you add one.
We’ve moved all of the generated code into the _generated directory to keep it organized now that there are multiple files.
Migration
- Run
npx convex codegen. This will delete the old code generated file and create the new ones. - Update all of your import paths from
convex/_generatedtoconvex/_generated/reactto import the React hooks from the new location. - Update all of your imports of
queryandmutationfromconvex-dev/servertoconvex/_generated/server.
If you don’t want to use code generation, you can still use the untyped versions of all of these functions:
queryGenericandmutationGenericfromconvex-dev/serveruseQueryGenericanduseMutationGenericfromconvex-dev/react
Breaking: db.update renamed to db.patch
We’ve renamed the db.update method in mutations to be called db.patch.
Rationale
The reasoning for this is that we’ve noticed some confusion around how db.update works.
db.update (now called db.patch) takes a partial version of a document and updates the specified fields to the new values. It doesn’t edit fields on the document that aren’t specified. For example you can create a document and update a single field on it with db.patch:
const id = db.insert("messages", {
message: "hello",
author: "Alex"
});
db.patch(id, {
message: "Hi!"
});
// The document still has the original author field and the new message.
This is in contrast to db.replace which will replace an entire document with a new object, overwriting all fields.
Migration
Switch all of the usages of db.update to use db.patch. If you find call sites that are setting all the properties of a document, you probably want db.replace instead.
TypeScript Type Checking
The Convex CLI will now run attempt TypeScript type checking on your Convex functions during npx convex push and npx convex codegen. This should help catch potential bugs early on and produce more readable error messages.
Extra Goodies
We also have a lot of small improvements that should make developing on Convex better than ever:
- There is now Next.js documentation that teaches you how to set up Convex in a Next.js app.
- The Convex CLI now updates your generated code during
npx convex pushso it doesn’t fall out of date. - Convex now works on Safari 14! It will also work on older versions of Safari as long as none of your functions use the
biginttype. - If you forget to include the
ConvexProviderin your app, there is now a helpful error message.