Developer Environment.

Everything runs locally from one repo with one command. This page covers the toolchain you install once, how the local stack comes up, and the inner-loop cycle you'll live in all day. Exact version pins and flags live in perkup-app/CLAUDE.md and the per-directory AGENTS.md files.

The toolchain

ToolRole
pnpmPackage manager for the whole workspace (version is pinned in the repo).
TurborepoTask runner — orchestrates build, test, and lint across every package with caching.
Node (pinned via .nvmrc)Runtime for the frontend, functions, and tooling.
JDK 21+Required by the Firebase emulators.
1Password CLIInjects secrets from the shared vault at runtime — no plaintext keys on disk.
Secrets are never committed. .env.local.default holds op:// references, and the 1Password CLI resolves them when you start the app. If a command fails on a missing secret, the fix is almost always "you're not signed in to 1Password," not "edit a file."

Running the stack

One command brings up the whole environment — frontend, functions, backend, Firebase emulators, and the supporting listeners. You can also bring up just the pieces you need:

CommandBrings up
pnpm op defaultThe full environment — frontend, backend, functions, emulators, and tunnels.
pnpm op emulateFirebase emulators + search only.
pnpm op developApp processes without the emulators (point at running emulators separately).

Inbound webhooks (Shopify, Stripe, and the like) reach your machine through a tunnel that the dev command starts for you. You generally won't think about it unless you're working on an integration — and then the Integrations page covers it.

The inner loop

The cycle you repeat dozens of times a day is: edit → check → run. Keep it fast and tight — the slower checks belong in CI, not on your keyboard.

  1. Edit. The dev server hot-reloads the frontend; functions and backend restart on change.
  2. Check. Before you push, run the fast local checks scoped to what you changed — formatter, linter, and the fast typechecker. A pre-commit hook runs a lightweight version of these on staged files automatically.
  3. Run. Exercise the change in the browser or with a targeted test. Prefer a fast unit test over clicking through the UI when you can.
Run the checks locally first. The same linters and type-checkers run in CI and post inline comments on your PR. Running them before you push is what keeps those comments — and the back-and-forth — from happening. Only fix findings in files your branch changed; main carries some pre-existing noise that isn't yours to clean up.

Everyday commands

CommandDoes
pnpm buildBuild all packages
pnpm testRun the test suites
pnpm lint · pnpm typecheckLint / type-check across the workspace

All of these run through Turbo, so they're cached and only re-run what changed. For pre-PR validation, scope them to the packages your branch touched rather than the whole repo — the pre-pr-checks skill in the repo spells out the exact incantation.

Source: perkup-app/CLAUDE.md · services/AGENTS.md · repo tooling config. Compiled 2026-06-07.