convex-quickstart

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
<!-- GENERATED from convex-agents content/capabilities/quickstart.json — do not edit by hand. -->
<!-- 由 convex-agents content/capabilities/quickstart.json 生成——请勿手动编辑。 -->

Quickstart: a barebones Convex template, running

快速入门:运行精简的 Convex 模板

Stand up a barebones Next.js + Convex template from the idea, locally, with an anonymous dev deployment. Minimal by design: local dev servers, no publish step, no pre-baked auth.
根据这一构想,在本地搭建一个精简的 Next.js + Convex 模板,并使用匿名开发部署。设计上保持最小化:仅使用本地开发服务器,不包含发布步骤,也不预置 auth。

Workflow

工作流

  1. Run recipe
    quickstart-recipe@^2
    with {idea, template} (the pack fetches + caches it; pinned offline fallback). It creates the project, installs deps, starts the backend (anonymous) and the web dev server.
  2. When it prints the dev URL, open it for the user.
  3. Present a short plan and CONFIRM before building features beyond the template.
  1. 运行 recipe
    quickstart-recipe@^2
    ,传入 {idea, template}(该 pack 会获取并缓存此 recipe,并提供固定版本的离线回退方案)。它会创建项目、安装依赖项、启动后端(匿名模式)和 Web 开发服务器。
  2. 当它输出开发 URL 时,为用户打开该 URL。
  3. 先给出简短计划并请求确认,然后再构建模板之外的功能。

Rules

规则

  • Never re-run the recipe if it already reported success.
  • Delegate any code under
    convex/
    to the
    convex-expert
    capability.
  • Don't add Postgres/Redis/Express — use Convex primitives.
  • Don't add hosting/publish or pre-baked auth here — keep the template minimal unless the user asks for more.
  • DEGRADATION RULE — if the scaffold cannot run (non-interactive session, no network, a sandboxed temp dir, or the user just wants code, not an app): skip the recipe and write a standard Convex project directly. ALL backend code goes under
    convex/
    (schema.ts, functions) — NEVER at the project root; Convex functions only run from the
    convex/
    directory. Write ZERO scaffold/documentation files (no START_HERE.md, ARCHITECTURE.md, MANIFEST.txt, README walls) unless explicitly asked. "Build me a backend" means code, not ceremony.
  • Data access + imports — before writing any convex/*.ts: never an unbounded
    .collect()
    on a table that can grow — use
    .withIndex(...)
    and
    .paginate(...)
    /
    .take(n)
    . Use an index, not
    .filter()
    , for anything that would be a SQL WHERE.
    .withIndex(...)
    callbacks only have
    eq
    /
    gt
    /
    gte
    /
    lt
    /
    lte
    — there is no
    .range(...)
    method. Imports:
    query
    /
    mutation
    /
    action
    /
    internalQuery
    /
    internalMutation
    /
    internalAction
    come from
    ./_generated/server
    ;
    api
    /
    internal
    come from
    ./_generated/api
    ; NEVER import from
    convex/server
    in application code.
    v.literal("exact value")
    for fixed string/enum members, not a bare string.
    "use node"
    only at the top of action-only modules — never in a file that also exports a
    query
    or
    mutation
    . Never import a Node builtin (
    crypto
    /
    fs
    /
    path
    /
    http
    /
    child_process
    /
    os
    , with or without the
    node:
    prefix) into a file lacking
    "use node"
    — including
    http.ts
    route handlers; use Web Crypto (
    crypto.subtle
    ) instead of
    import
    ing
    crypto
    where possible.
  • Reserved names — never
    export const <jsReservedWord> = ...
    (e.g.
    delete
    ,
    new
    ,
    class
    ,
    function
    ,
    return
    ) as a query/mutation/action export name; esbuild fails to parse it. Never a table or index name starting with
    _
    (e.g.
    _migrations: defineTable(...)
    ) —
    _
    is reserved and errors at push as
    TableNameReserved
    /
    IndexNameReserved
    .
  • HTTP routes —
    httpRouter
    has no Express-style
    :param
    segments (
    path: "/users/:id"
    only matches that literal string and is dead code); use
    pathPrefix
    and parse the trailing segment yourself. Every
    http.route({...})
    handler:
    must be wrapped in
    httpAction(...)
    from
    ./_generated/server
    — a bare
    async (ctx, request) => {...}
    type-checks but isn't a valid HTTP action.
  • ctx.runQuery
    /
    ctx.runMutation
    /
    ctx.runAction
    need a codegen'd function reference (
    api.foo.bar
    /
    internal.foo.bar
    ), never a raw imported module member (
    import * as queries from "./queries"; ctx.runQuery(queries.getX, ...)
    compiles but fails at runtime).
  • SELF-VERIFY RULE — before declaring backend work done, verify it compiles and pushes: run
    npx tsc --noEmit
    and push it to a deployment. Prefer the project's existing one; otherwise
    npx convex dev --once
    when
    npx convex whoami
    succeeds, and
    CONVEX_AGENT_MODE=anonymous npx convex dev --once
    ONLY when it does not. Forcing anonymous on a signed-in user rebinds
    .env.local
    and costs them the persistent, publishable cloud deployment they expect. Fix every error it reports before finishing — one verify round catches the wrong-relative-import / duplicate-symbol / unbalanced-paren class that otherwise breaks the deploy.
  • 如果 recipe 已经报告成功,切勿重新运行。
  • 将
    convex/
    下的所有代码委托给
    convex-expert
    capability 处理。
  • 不要添加 Postgres/Redis/Express——应使用 Convex 原语。
  • 此处不要添加托管或发布功能,也不要预置 auth——除非用户明确要求,否则应保持模板精简。
  • 降级规则——如果脚手架无法运行(处于非交互式会话、无网络、使用沙箱临时目录,或者用户只需要代码而不需要可运行的应用):跳过 recipe,直接编写一个标准的 Convex 项目。所有后端代码都必须放在
    convex/
    下(
    schema.ts
    、functions)——绝不能放在项目根目录;Convex functions 只能从
    convex/
    目录运行。不要编写任何脚手架或文档文件(不要创建 START_HERE.md、ARCHITECTURE.md、MANIFEST.txt 或大段 README),除非用户明确要求。“为我构建一个后端”指的是提供代码,而不是繁文缛节。
  • 数据访问与导入——在编写任何
    convex/*.ts
    之前:对于可能不断增长的表,绝不能使用无界
    .collect()
    ——应使用
    .withIndex(...)
    和
    .paginate(...)
    /
    .take(n)
    。任何相当于 SQL WHERE 的逻辑都应使用 index,而不是
    .filter()
    。
    .withIndex(...)
    回调仅支持
    eq
    /
    gt
    /
    gte
    /
    lt
    /
    lte
    ——不存在
    .range(...)
    方法。导入:
    query
    /
    mutation
    /
    action
    /
    internalQuery
    /
    internalMutation
    /
    internalAction
    来自
    ./_generated/server
    ;
    api
    /
    internal
    来自
    ./_generated/api
    ;应用程序代码中绝不能从
    convex/server
    导入。对于固定的字符串或枚举成员,使用
    v.literal("exact value")
    ,不要使用裸字符串。
    "use node"
    只能放在仅包含 action 的模块顶部——绝不能放在同时导出
    query
    或
    mutation
    的文件中。绝不能将任何 Node 内置模块(
    crypto
    /
    fs
    /
    path
    /
    http
    /
    child_process
    /
    os
    ,无论是否带
    node:
    前缀)导入缺少
    "use node"
    的文件——包括
    http.ts
    路由处理器;尽可能使用 Web Crypto(
    crypto.subtle
    ),而不是
    import
    crypto
    。
  • 保留名称——绝不能使用
    export const <jsReservedWord> = ...
    (例如
    delete
    、
    new
    、
    class
    、
    function
    、
    return
    )作为 query/mutation/action 的导出名称;esbuild 将无法解析。表名或 index 名绝不能以下划线
    _
    开头(例如
    _migrations: defineTable(...)
    )——
    _
    是保留前缀,推送时会触发
    TableNameReserved
    /
    IndexNameReserved
    错误。
  • HTTP 路由——
    httpRouter
    不支持 Express 风格的
    :param
    路径段(
    path: "/users/:id"
    只会匹配该字面字符串,属于无效代码);应使用
    pathPrefix
    ,并自行解析末尾的路径段。每个
    http.route({...})
    的
    handler:
    都必须使用
    ./_generated/server
    中的
    httpAction(...)
    包装——直接使用
    async (ctx, request) => {...}
    虽然可以通过类型检查,但并不是有效的 HTTP action。
  • ctx.runQuery
    /
    ctx.runMutation
    /
    ctx.runAction
    需要使用经过代码生成的函数引用(
    api.foo.bar
    /
    internal.foo.bar
    ),绝不能使用原始导入的模块成员(
    import * as queries from "./queries"; ctx.runQuery(queries.getX, ...)
    虽然可以编译,但运行时失败)。
  • 自我验证规则——在宣布后端工作完成之前,验证其能够编译并推送:运行
    npx tsc --noEmit
    ,并将其推送到部署。优先使用项目已有的部署;否则,当
    npx convex whoami
    成功时使用
    npx convex dev --once
    ,仅当该命令失败时才使用
    CONVEX_AGENT_MODE=anonymous npx convex dev --once
    。对已登录用户强制使用匿名模式会重新绑定
    .env.local
    ,并使其失去预期的持久化、可发布云部署。完成前必须修复它报告的所有错误——一轮验证即可发现相对路径导入错误、重复符号、括号不配对等原本会导致部署失败的问题。