Convex Patterns

Design your schema

Define Convex tables, validators, and indexes that support the queries and mutations used from Nuxt or Vue.

Your frontend API is only as predictable as the schema behind it. Use this page to shape the tables and indexes that the shared runtime will query.

Start with the fields you actually read

convex/schema.ts
import { defineSchema, defineTable } from 'convex/server'
import { v } from 'convex/values'

export default defineSchema({
  tasks: defineTable({
    title: v.string(),
    userId: v.optional(v.string()),
    isCompleted: v.boolean(),
    createdAt: v.number(),
  }).index('by_user', ['userId']),
})

Run npx convex dev after schema changes so the generated API stays in sync with the docs examples and your app code.

Add indexes for the queries you expect

The frontend helpers do not hide slow query design. If your UI filters or sorts by a field, design the index for that access pattern.

ctx.db
  .query('tasks')
  .withIndex('by_user', q => q.eq('userId', userId))
  .order('desc')
  .take(20)

For compound filters, define a compound index in the same order as the equality filters you apply before the range or sort behavior.

Use v.id('tableName') for document relationships and keep the shape consistent with the mutations and queries you plan to expose.

Next steps

Copyright © 2026