Skip to content

Local Development Workflows

Local development in Wavemap is split between workspace package watchers, app runtimes, Docker-backed backend services, generated assets, and browser test runners. Use this page to choose the right local loop before reaching for deployed-dev commands.

This page is for developer-machine setup and local verification. Shared cloud environments, deployed runtime config, and operator recovery paths live in the operations docs.

LoopUse ForPrimary Commands
Docker-backed backend, local frontendNormal app development with local Postgres, seeded data, dependent packages watching for changes, and dev server Next.js.pnpm dev:docker:up, then pnpm -C apps/wavemap-front-end dev.
Non-Docker local watchersLocal services already exist and you want package/backend/frontend watchers in one terminal.pnpm dev.
Package developmentShared package contract or utility work.pnpm -F @wavemap/api-contracts dev, pnpm -F @wavemap/i18n dev, package tests.
Browser E2E local debuggingReal browser behavior against local runtimes.pnpm test:e2e:prepare, frontend dev, then front-end Playwright commands.
CI-style built frontendBuild/runtime parity for Playwright or production-like checks.Build i18n assets, pnpm -C apps/wavemap-front-end build, then start.
Docs site workStarlight content and navigation changes.pnpm -C apps/wavemap-docs dev, pnpm build:docs.

Prefer the Docker-backed backend plus local frontend for most product work. The front-end Docker compose path exists, but local next dev is the ordinary faster loop on macOS and Windows.

The app .env.example files document the local values expected by each runtime:

  • apps/wavemap-back-end/.env.example
  • apps/wavemap-front-end/.env.example
  • packages/i18n/.env.example

Local .env.dev and .env.shared files are not tracked in git. Create local files from the example values and keep real secrets out of the repository.

Important local boundaries:

  • Frontend browser values use NEXT_PUBLIC_* and are visible to the browser.
  • Frontend server-only values do not use the NEXT_PUBLIC_* prefix.
  • Backend runtime values are consumed by the backend env parser and Docker Compose.
  • Shared i18n values exist in both frontend and backend-facing forms so the app and package agree on locale, namespace, and asset version behavior.
  • Local development values should not be copied into deployed-dev SSM, GitHub environments, or Pulumi config just because they have the same names.

Use Configuration And Secrets when adding, renaming, or moving an environment value.

The main local backend path is:

Terminal window
pnpm dev:docker:up

That command starts the shared-package watcher manager in the background, waits for a visible watcher readiness checklist, starts the backend development Compose stack, resolves the active local media mode from the backend env file, waits for database and API health, resets local media emulator state where that reset is wired, and reseeds the development database baseline.

The watcher readiness checklist is the signal that @wavemap/shared-utils, @wavemap/api-contracts, and @wavemap/i18n have completed their initial TypeScript builds and that tsc-alias is watching their dist outputs:

Shared package watchers ready:
[OK] shared-utils: tsc ready, tsc-alias ready
[OK] api-contracts: tsc ready, tsc-alias ready
[OK] i18n: tsc ready, tsc-alias ready

Detailed watcher output is written to .wavemap/dev/shared-watchers.log.

Then run the frontend locally:

Terminal window
pnpm -C apps/wavemap-front-end dev

Default local URLs:

  • Frontend: http://localhost:3000
  • Backend: http://localhost:6000

Useful stack controls:

Terminal window
pnpm dev:docker:stop
pnpm dev:docker:reload
pnpm dev:docker:down
pnpm dev:docker:hard-reload
pnpm dev:packages:stop

stop and reload preserve local volumes. down and hard-reload remove Compose volumes and are better when local service state is suspected to be stale. dev:docker:stop and dev:docker:down also stop the background shared-package watchers started by dev:docker:up. Use dev:packages:stop only when you need to stop those watchers without touching Docker. Use SKIP_DOCKER_WATCHERS=1 pnpm dev:docker:up when you intentionally do not want Docker startup to manage package watchers.

The root command:

Terminal window
pnpm dev

uses the cross-platform local dev process manager. It runs these watcher/runtime processes in one terminal:

  • @wavemap/shared-utils
  • @wavemap/api-contracts
  • @wavemap/i18n
  • wavemap-back-end
  • wavemap-front-end

Use this loop when the required local services and env values already exist. The @wavemap/i18n watcher keeps package source exports flowing into dist for the app runtimes, while ordinary translation JSON edits are still read directly by local next dev through the rewrite-backed i18n asset routes.

Press Ctrl-C in the pnpm dev terminal to stop all child processes.

To run only the shared package watchers, use:

Terminal window
pnpm dev:packages

When pnpm dev:docker:up starts shared package watchers in the background, stop them with:

Terminal window
pnpm dev:packages:stop

Local media behavior is selected through backend env values:

  • MEDIA_STORAGE_PROVIDER
  • MEDIA_STORAGE_EXECUTION_TARGET
  • MEDIA_STORAGE_APPLICATION_ENVIRONMENT

Current local modes:

ModeEnv ShapeUse For
Mocked storageProvider: mocked
Target: mocked
App env: development or test.
Day-to-day app logic and tests that do not need object-store behavior.
S3 emulatorProvider: s3
Target: emulator
App env: development or test.
Local AWS-shaped upload/delete/path behavior through LocalStack.
Azure emulatorProvider: azure
Target: emulator
App env: development.
Azure continuity smoke through Azurite.
Real S3 validationProvider: s3
Target: cloud
App env: development, test, staging, and prod eventually.
Explicit real-cloud validation only, using the normal AWS SDK chain.

When MEDIA_STORAGE_APPLICATION_ENVIRONMENT is omitted, the backend falls back to NODE_ENV. When MEDIA_STORAGE_EXECUTION_TARGET is omitted, development and test resolve to emulator, while staging and production resolve to cloud.

Emulators are execution targets, not persisted providers. LocalStack and Azurite should not appear as stored media provider values.

pnpm dev:docker:up adds the S3 or Azure emulator compose layer only when the selected provider/target requires it. S3 emulator media reset is wired for LocalStack; Azure emulator reset remains a continuity-path gap. Real cloud media validation must stay explicit and should not be targeted by generic local reset commands.

Use Media Workflow And Validation for choosing the right media proof lane. Use Media Storage And Delivery for the durable media architecture boundary.

In local next dev, i18n asset requests are rewritten to API routes that read from packages/i18n/locales. Ordinary translation edits therefore do not require regenerating frontend public assets on every save.

Production-like frontend builds need a generated static snapshot:

Terminal window
pnpm -C packages/i18n build-and-validate:i18n-assets

Run that before frontend build/start flows when you need built-runtime parity:

Terminal window
pnpm -C packages/i18n build-and-validate:i18n-assets
pnpm -C apps/wavemap-front-end build
pnpm -C apps/wavemap-front-end start

Use i18n Assets And Delivery for the full asset and CDN boundary.

Playwright does not start the app runtime for you. Start the backend and frontend first, then run browser tests.

Default local sequence:

Terminal window
pnpm dev:docker:up
pnpm test:e2e:prepare
pnpm -C apps/wavemap-front-end exec playwright install chromium

Start the frontend in its own shell:

Terminal window
pnpm -C apps/wavemap-front-end dev

Then run the smoke suite from another shell once http://localhost:3000 is serving:

Terminal window
pnpm -C apps/wavemap-front-end test:e2e:smoke

pnpm test:e2e:prepare builds the shared workspace packages whose package exports point at dist outputs. This keeps front-end Playwright imports aligned with package export behavior.

CI smoke uses a built frontend runtime instead of next dev so browser timing reflects built artifacts rather than on-demand route compilation:

Terminal window
pnpm -C packages/i18n build-and-validate:i18n-assets
pnpm -C apps/wavemap-front-end build

Start the built runtime in its own shell:

Terminal window
PLAYWRIGHT_FRONTEND_RUNTIME=build pnpm -C apps/wavemap-front-end start

Then run smoke against that built runtime from another shell:

Terminal window
pnpm -C apps/wavemap-front-end test:e2e:smoke -- --project=chromium

Use Testing for layer selection and browser-suite scope.

Useful local verification commands:

Terminal window
pnpm test:packages
pnpm test:unit
pnpm verify:i18n
pnpm verify:scripts
pnpm build:docs
pnpm -C apps/wavemap-docs dev

Prefer package-scoped commands when changing one package:

Terminal window
pnpm -F @wavemap/api-contracts test
pnpm -F @wavemap/i18n test
pnpm -F @wavemap/shared-utils test
pnpm -C apps/wavemap-front-end test:ci
pnpm -C apps/wavemap-back-end test:ci

Local development commands should not silently:

  • Run Pulumi.
  • Mutate deployed-dev runtime hosts.
  • Populate SSM parameters.
  • Push Docker images.
  • Publish docs to S3/CloudFront.
  • Reset deployed-dev data.
  • Use real cloud media storage without an explicit validation choice.

When the task crosses those boundaries, switch to the operations docs and move through the appropriate approval gates.