Convex Turbo Monorepo

A reusable Bun/Turborepo template with Next.js 16, Expo, self-hosted Convex, shared UI/config packages, Vitest, and Docker deployment.

Local setup

Requirements: Bun 1.3.10, Docker or Podman, Node 22, and the Infisical CLI.

bun install --frozen-lockfile
infisical login
infisical init
bun db:up
bun dev:next

The committed .infisical.json links this repository to its own Infisical project. Local commands read dev by default and never fall back to .env files. Select staging with INFISICAL_ENV=staging bun dev:next.

Local services:

  • Next.js: http://localhost:3000
  • Convex API: http://localhost:3210
  • Convex dashboard: http://localhost:6791

Next and Expo run on the host. Convex uses a self-hosted data volume and does not use Postgres by default. The commented POSTGRES_URL in Compose is an opt-in example for cloned projects that explicitly choose Convex-on-Postgres.

bun db:down        # stop; preserve Convex data
bun db:down:wipe   # remove the Convex volume and generated admin key

Normal bun db:up never contacts staging and does not start Postgres. It starts the local Convex backend and dashboard, generates a machine-local Convex admin key in .local/dev.generated.env when needed, deploys functions/schema, and configures local Convex Auth keys.

Physical devices cannot resolve their own localhost; override the public Convex URL with the development host's LAN address when testing Expo on-device.

Environment model

  • Local dev and staging: Infisical.
  • Generated local state: .local/<environment>.generated.env.
  • CI/CD: Gitea DOTENV_PROD, materialized only as a temporary runner file.
  • Docker compilation: explicit Compose build args; .env* stays outside the image context.

Run sh scripts/with-env dev -- <command> for an environment-aware command or sh scripts/export-env dev to materialize a temporary merged dotenv stream. Do not commit or maintain root .env files.

Development and quality

bun dev:next
bun dev:expo
bun lint:ws
bun format
bun lint
bun typecheck
bun test:unit
bun test:integration
bun test:component
SKIP_E2E=1 bun run ci:check

bun test:e2e starts the isolated local stack and currently performs generic stack smoke checks. It skips in CI and when SKIP_E2E=1 is set.

Shared dependency versions belong in root catalogs. Edit the root catalog, run bun install, then bun lint:ws; do not run bun update inside a workspace.

Deployment

Production Compose retains the self-hosted Convex backend/dashboard and has no Postgres service by default. A commented POSTGRES_URL remains only as an optional Convex-on-Postgres example for cloned projects. Gitea runs the quality gate first, builds the Next image from a temporary Gitea-secret env file, then pushes SHA and latest tags. CI never installs or invokes Infisical.

S
Description
Convex Monorepo with Next.js & Expo
Readme 6.1 MiB
Languages
TypeScript 90.8%
JavaScript 3.2%
Shell 3.1%
CSS 2.1%
Dockerfile 0.5%
Other 0.3%