# convex-lite at https://convex.edifear.com convex-lite is a small backend that speaks the public Convex contract. You write standard Convex code (schema, queries, mutations, actions, `v.*` validators) and use the unmodified `convex@1.46.0` npm client. This server hosts your functions and data; your frontend can run anywhere, including localhost. Read this whole file before writing code. Everything an agent needs is here. ## 1. Project setup npm install convex@1.46.0 mkdir convex Get the CLI (one-time, any machine): git clone https://github.com/Edifear/convex-lite ~/convex-lite cd ~/convex-lite && npm ci --ignore-scripts && npm run build export CONVEX_LITE=~/convex-lite/bin/convex-lite.js You need the admin key for pushing code (ask the server owner). Set it once: export CONVEX_ADMIN_KEY=... ## 2. Write functions (standard Convex) `convex/schema.ts`: import { defineSchema, defineTable } from "convex/server"; import { v } from "convex/values"; export default defineSchema({ todos: defineTable({ text: v.string(), done: v.boolean() }).index("by_done", ["done"]), }); `convex/todos.ts`: import { v } from "convex/values"; import { mutation, query } from "./_generated/server"; export const list = query({ args: {}, handler: async (ctx) => ctx.db.query("todos").order("desc").collect(), }); export const add = mutation({ args: { text: v.string() }, handler: async (ctx, { text }) => ctx.db.insert("todos", { text, done: false }), }); Rules: - Every function must declare `args` validators; the server validates them. - Queries are read-only and deterministic (`Date.now()` is frozen, `Math.random()` seeded, no fetch). - Mutations are transactions: all writes commit or none. One mutation at a time per app. - Actions may use `fetch` and call other functions with `ctx.runQuery` / `ctx.runMutation` / `ctx.runAction`. - `internalQuery` / `internalMutation` / `internalAction` are not callable from clients. - An action that references `api..` needs an explicit return type annotation (TypeScript circular inference). ## 3. Push and develop Watch `convex/` and push on every change (no local backend): node $CONVEX_LITE dev --url https://convex.edifear.com --dir convex This also generates `convex/_generated/` and writes `.env.local` with `CONVEX_URL` and `VITE_CONVEX_URL=https://convex.edifear.com`. One-off deploy: CONVEX_URL=https://convex.edifear.com node $CONVEX_LITE push --dir convex ## 4. Frontend import { ConvexProvider, ConvexReactClient } from "convex/react"; const client = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL); // useQuery(api.todos.list, {}), useMutation(api.todos.add), useAction, usePaginatedQuery `convex/react` and `convex/browser` work unchanged: live queries over WebSocket, optimistic updates, pagination, `ConvexHttpClient`. CORS is open, so localhost works. ## 5. Call functions without a client (curl) curl -s -X POST https://convex.edifear.com/api/query \ -H 'Content-Type: application/json' \ -d '{"path":"todos:list","args":[{}]}' curl -s -X POST https://convex.edifear.com/api/mutation \ -H 'Content-Type: application/json' \ -d '{"path":"todos:add","args":[{"text":"hello"}]}' Also `/api/action`. `path` is `module:export` (`users/profile:get` for nested files). Responses: `{"status":"success","value":...,"logLines":[...]}` or HTTP 560 with `{"status":"error","errorMessage":"...","errorData":...}`. ## 6. Inspect (needs `Authorization: Bearer $CONVEX_ADMIN_KEY`) node $CONVEX_LITE tables --url https://convex.edifear.com node $CONVEX_LITE data todos --url https://convex.edifear.com --limit 20 node $CONVEX_LITE logs --url https://convex.edifear.com --limit 50 node $CONVEX_LITE run todos:list --url https://convex.edifear.com Raw: GET /api/inspect/functions, /api/inspect/tables, /api/inspect/data?table=todos&limit=100, /api/inspect/logs?limit=100. ## 7. What works, what does not (v0) Works: schema + indexes (`by_id`, `by_creation_time`, `.index()`), `db.get/insert/patch/replace/delete`, `withIndex` ranges (`eq`, `gt`, `gte`, `lt`, `lte`), `order`, `filter`, `take/first/unique/collect`, `paginate`, full nested documents, all Convex value types, `ConvexError`, `console.log` in logs, live subscriptions with per-index-range invalidation, actions with `fetch`. Not yet (each returns a clear `NotSupported` error): - auth: `ctx.auth.getUserIdentity()` always returns `null` - `ctx.scheduler` (runAfter/runAt) and cron jobs - `ctx.storage` (file storage) - HTTP actions (`httpRouter`) - `ctx.runQuery` / `ctx.runMutation` inside queries/mutations (fine inside actions) - full-text and vector search, components, Node.js runtime actions ## 8. Limits (per function call) and error codes - 16 384 documents read, 8 MiB read, 8 192 writes, 1 MiB per document, 16 levels of nesting - 10 s for queries/mutations, 60 s for actions, 64 MiB isolate memory - Codes: ArgumentValidationError, SchemaValidation, FunctionNotFound, FunctionTypeMismatch, IndexNotFound, InvalidIndexRange, RowsReadLimit, BytesReadLimit, WritesLimit, DocumentTooLarge, DocumentNotFound, NotAllowedInQueryOrMutation, FunctionTimeout, NotSupported. Every message says what to change. ## 9. Important: one shared app This server currently hosts a single app (`default`). Everyone who pushes replaces the same function set and shares the same tables. Use unique table names or coordinate before pushing. Per-project apps (`.convex.edifear.com`) are planned. Demo: https://convex.edifear.com/todo/ ยท Source: https://github.com/Edifear/convex-lite