Receber por email
← Voltar para o catálogo

convex

Convex reactive backend expert: schema design, TypeScript functions, real-time subscriptions, auth, file storage, scheduling, and deployment.

41.2kestrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add sickn33/antigravity-awesome-skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/convex-mpte4pxt/svg)](https://www.skillteca.com.br/skills/convex-mpte4pxt)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Convex

You are an expert in Convex — the open-source, reactive backend platform where queries are TypeScript code. You have deep knowledge of schema design, function authoring (queries, mutations, actions), real-time data subscriptions, authentication, file storage, scheduling, and deployment workflows across React, Next.js, Angular, Vue, Svelte, React Native, and server-side environments.

When to Use

  • Use when building a new project with Convex as the backend
  • Use when adding Convex to an existing React, Next.js, Angular, Vue, Svelte, or React Native app
  • Use when designing schemas for a Convex document-relational database
  • Use when writing or debugging Convex functions (queries, mutations, actions)
  • Use when implementing real-time/reactive data patterns
  • Use when setting up authentication with Convex Auth or third-party providers (Clerk, Auth0, etc.)
  • Use when working with Convex file storage, scheduled functions, or cron jobs
  • Use when deploying or managing Convex projects

Core Concepts

Convex is a document-relational database with a fully managed backend. Key differentiators:

  • Reactive by default: Queries automatically re-run and push updates to all connected clients when underlying data changes
  • TypeScript-first: All backend logic — queries, mutations, actions, schemas — is written in TypeScript
  • ACID transactions: Serializable isolation with optimistic concurrency control
  • No infrastructure to manage: Serverless, scales automatically, zero config
  • End-to-end type safety: Types flow from schema → backend functions → client hooks

Function Types

| Type | Purpose | Can Read DB | Can Write DB | Can Call External APIs | Cached/Reactive | | :-------------- | :------------------------ | :------------- | :---------------- | :--------------------- | :-------------- | | Query | Read data | ✅ | ❌ | ❌ | ✅ | | Mutation | Write data | ✅ | ✅ | ❌ | ❌ | | Action | Side effects | via runQuery | via runMutation | ✅ | ❌ | | HTTP Action | Webhooks/custom endpoints | via runQuery | via runMutation | ✅ | ❌ |

Project Setup

New Project (Next.js)

npx create-next-app@latest my-app
cd my-app && npm install convex
npx convex dev

Add to Existing Project

npm install convex
npx convex dev

The npx convex dev command:

  1. Prompts you to log in (GitHub)
  2. Creates a project and deployment
  3. Generates convex/ folder for backend functions
  4. Syncs functions to your dev deployment in real-time
  5. Creates .env.local with CONVEX_DEPLOYMENT and NEXT_PUBLIC_CONVEX_URL

Folder Structure

my-app/
├── convex/
│   ├── _generated/        ← Auto-generated (DO NOT EDIT)
│   │   ├── api.d.ts
│   │   ├── dataModel.d.ts
│   │   └── server.d.ts
│   ├── schema.ts          ← Database schema definition
│   ├── tasks.ts           ← Query/mutation functions
│   └── http.ts            ← HTTP actions (optional)
├── .env.local             ← CONVEX_DEPLOYMENT, NEXT_PUBLIC_CONVEX_URL
└── convex.json            ← Project config (optional)

Schema Design

Define your schema in convex/schema.ts using the validator library:

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

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

  messages: defineTable({
    authorId: v.id("users"),
    channelId: v.id("channels"),
    body: v.string(),
    attachmentId: v.optional(v.id("_storage")),
  })
    .index("by_channel", ["channelId"])
    .searchIndex("search_body", { searchField: "body" }),

  channels: defineTable({
    name: v.string(),
    description: v.optional(v.string()),
    isPrivate: v.boolean(),
  }),
});

Validator Types

| Validator | TypeScript Type | Notes | | :-------------------------------- | :-------------------- | :--------------------------------------------- | | v.string() | string | | | v.number() | number | IEEE 754 float | | v.bigint() | bigint | | | v.boolean() | boolean | | | v.null() | null | | | v.id("tableName") | Id<"tableName"> | Document reference | | v.array(v.string()) | string[] | | | v.object({...}) | {...} | Nested objects | | v.optional(v.string()) | string \| undefined | | | v.union(v.string(), v.number()) | string \| number | | | v.literal("active") | "active" | Literal types | | v.bytes() | ArrayBuffer | Binary data | | v.float64() | number | Explicit 64-bit float (used in vector indexes) | | v.any() | any | Escape hatch |

Indexes

// Single-field index
defineTable({ email: v.string() }).index("by_email", ["email"]);

// Compound index (order matters for range queries)
defineTable({
  orgId: v.string(),
  createdAt: v.number(),
}).index("by_org_and_date", ["orgId", "createdAt"]);

// Full-text search index
defineTable({ body: v.string(), channelId: v.id("channels") }).searchIndex(
  "search_body",
  {
    searchField: "body",
    filterFields: ["channelId"],
  },
);

// Vector search index (for AI/embeddings)
defineTable({ embedding: v.array(v.float64()), text: v.string() }).vectorIndex(
  "by_embedding",
  {
    vectorField: "embedding",
    dimensions: 1536,
  },
);

Writing Functions

Queries (Read Data)

Queries are reactive — clients automatically get updates when data changes.

import { query } from "./_generated/server";
import { v } from "convex/values";

// Simple query — list all tasks
export const list = query({
  args: {},
  handler: async (ctx) => {
    return await ctx.db.query("tasks").collect();
  },
});

// Query with arguments and filtering
export const getByChannel = query({
  args: { channelId: v.id("channels") },
  handler: async (ctx, args) => {
    return await ctx.db
      .query("messages")
      .withIndex("by_channel", (q) => q.eq("channelId", args.channelId))
      .order("desc")
      .take(50);
  },
});

// Query with auth check
export const getMyProfile = query({
  args: {},
  handler: async (ctx) => {
    const identity = await ctx.auth.getUserIdentity();
    if (!identity) return null;

    return await ctx.db
      .query("users")
      .withIndex("by_token", (q) =>
        q.eq("tokenIdentifier", identity.tokenIdentifier),
      )
      .unique();
  },
});

### Paginated Queries

Use cursor-based pagination for lists or infinite scroll UIs.

import { query } from "./_generated/server"; import { paginationOptsValidator } from "convex/server";

export const listPaginated = query({ args: {

Compartilhar X LinkedIn