Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
waynesutton avatar

Schema Builder

  • 2 installs
  • 627 repo stars
  • Updated May 20, 2026
  • waynesutton/markdown-site

Designs and generates Convex database schemas with proper validation, indexes, and document-relational relationships in schema.ts.

About

This skill builds well-structured Convex schemas following document-relational, indexing, and validator best practices. A developer uses it when creating or modifying schema.ts, adding tables, designing relationships, or optimizing indexes.

  • Document-relational design with indexed foreign keys
  • Limits arrays to small bounded collections

Schema Builder by the numbers

  • 2 all-time installs (skills.sh)
  • +1 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #743 of 911 Databases skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/waynesutton/markdown-site --skill schema-builder

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs2
repo stars627
Last updatedMay 20, 2026
Repositorywaynesutton/markdown-site

What it does

Designs and generates Convex database schemas with proper validation, indexes, and document-relational relationships in schema.ts.

Files

SKILL.mdMarkdownGitHub ↗

Convex Schema Builder

Build well-structured Convex schemas following best practices for relationships, indexes, and validators.

When to Use

  • Creating a new convex/schema.ts file
  • Adding tables to existing schema
  • Designing data model relationships
  • Adding or optimizing indexes
  • Converting nested data to relational structure

Schema Design Principles

1. Document-Relational: Use flat documents with ID references, not deep nesting 2. Index Foreign Keys: Always index fields used in lookups (userId, teamId, etc.) 3. Limit Arrays: Only use arrays for small, bounded collections (<8192 items) 4. Type Safety: Use strict validators with v.* types

Schema Template

import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

export default defineSchema({
  tableName: defineTable({
    field: v.string(),
    optional: v.optional(v.number()),
    userId: v.id("users"),
    status: v.union(
      v.literal("active"),
      v.literal("pending"),
      v.literal("archived")
    ),
    createdAt: v.number(),
    updatedAt: v.optional(v.number()),
  })
    .index("by_user", ["userId"])
    .index("by_user_and_status", ["userId", "status"])
    .index("by_created", ["createdAt"]),
});

Common Patterns

One-to-Many Relationship

export default defineSchema({
  users: defineTable({
    name: v.string(),
    email: v.string(),
  }).index("by_email", ["email"]),

  posts: defineTable({
    userId: v.id("users"),
    title: v.string(),
    content: v.string(),
  }).index("by_user", ["userId"]),
});

Many-to-Many with Junction Table

export default defineSchema({
  users: defineTable({ name: v.string() }),
  projects: defineTable({ name: v.string() }),
  projectMembers: defineTable({
    userId: v.id("users"),
    projectId: v.id("projects"),
    role: v.union(v.literal("owner"), v.literal("member")),
  })
    .index("by_user", ["userId"])
    .index("by_project", ["projectId"])
    .index("by_project_and_user", ["projectId", "userId"]),
});

Hierarchical Data

export default defineSchema({
  comments: defineTable({
    postId: v.id("posts"),
    parentId: v.optional(v.id("comments")),
    userId: v.id("users"),
    text: v.string(),
  })
    .index("by_post", ["postId"])
    .index("by_parent", ["parentId"]),
});

Validator Reference

v.string()
v.number()
v.boolean()
v.null()
v.id("tableName")
v.optional(v.string())
v.union(v.literal("a"), v.literal("b"))
v.object({ key: v.string(), nested: v.number() })
v.array(v.string())
v.record(v.string(), v.boolean())
v.any()

Index Strategy

1. Single-field indexes: For simple lookups (by_user: ["userId"]) 2. Compound indexes: For filtered queries (by_user_and_status: ["userId", "status"]) 3. Remove redundant: by_a_and_b usually covers by_a

Checklist

  • [ ] All foreign keys have indexes
  • [ ] Common query patterns have compound indexes
  • [ ] Arrays are small and bounded (or converted to relations)
  • [ ] All fields have proper validators
  • [ ] Enums use v.union(v.literal(...)) pattern
  • [ ] Timestamps use v.number() (milliseconds since epoch)

Source: https://github.com/get-convex/convex-agent-plugins

Related skills

Databasesdatabases

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.