Skip to main content

Building Features

Use this process before adding a new route, UI flow, or backend module to the starter.

Before Implementation

  1. Confirm the owning surface:
    • apps/app org
    • apps/app portal
    • apps/app platform
    • apps/marketing
    • packages/backend/convex
  2. Confirm whether the work is route-local, surface-local, or truly shared.
  3. Confirm what data it reads and writes.
  4. Confirm whether it needs new navigation, permissions, capabilities, or backend endpoints.
  5. Confirm which docs need updating if the starter mental model changes.

Placement Rules

Product app UI

  • Keep route entrypoints in apps/app/src/app/[locale]/**.
  • Keep the page body in page.tsx by default.
  • Keep route-local support code in _components/*, _hooks/*, and _lib/* next to the owning route tree.
  • Promote code into apps/app/src/app/[locale]/_components/*, _hooks/*, and _lib/* only when reuse across surfaces is proven.

Marketing UI

  • Keep public marketing routes and presentation inside apps/marketing/src/**.
  • Do not mix tenant or authenticated product flows into the marketing app.

Backend work

  • Author all Convex modules in packages/backend/convex/**.
  • Do not add authored backend files under apps/app/convex.
  • Use explicit, owning domain names for modules and folders.

Naming Rules

  • Route names should be product-shaped and user-facing.
  • Avoid tutorial or temporary names such as /demo, /test, or /server.
  • Backend modules should be domain-specific, not catch-all helpers.

Good backend names:

  • org/access.ts
  • portal/profile.ts
  • platform/directory.ts
  • notifications/inbox.ts

Avoid:

  • helpers.ts
  • data.ts
  • myFunctions.ts

Docs To Update When Relevant

  • docs/app/README.md
  • docs/app/foundation/architecture.md
  • the relevant starter app spec in docs/app/apps/*
  • docs/dev/README.md when developer onboarding changes
  • the specific backend or integration docs in docs/dev/** when implementation details change

Definition Of Done

A feature is not done until:

  • ownership is clear
  • naming matches the starter model
  • backend changes live in packages/backend/convex/**
  • app routes live in the correct surface tree
  • docs are updated when the architecture or onboarding story changed
  • lint, typecheck, and the narrowest relevant tests pass