Prerequisites & access
Last reviewed against the codebase: 2026-07-25.
What to install and which access to request before you run the stack, and - just
as important - why each piece is pinned the way it is. The versions below are
the ones the repository is pinned to; matching them exactly is the difference
between pnpm install succeeding on the first try and spending an afternoon
chasing a native-binary or lockfile mismatch.
There are two distinct tiers of setup, and most contributors only ever need the first:
- Local development - Node, pnpm, and Docker. No external accounts. The app auto-logs in on first fetch and pulls live public data, so you can have the full stack running against real satellite hotspots without a single credential.
- Operating the hosted environment - additionally AWS SSO, the AWS CLI, Terraform, and (for mobile builds) EAS. This is only for waking, deploying, or hibernating the production stack, and is gated behind access you request from the project owner.
Tools & versions
| Tool | Version | Why this version |
|---|---|---|
| Node.js | 22.16.0 (pinned in .tool-versions) | Runs the API server, the Expo web build, and the doc generators. The same 22.16.0 is pinned as the EAS build image (eas.json → build.base.node), so local and cloud builds are byte-for-byte consistent. |
| pnpm | 11.0.9 (packageManager: pnpm@11.0.9) | The only supported package manager - this is a pnpm workspace with a catalog, platform-binary overrides, and a supply-chain guard that npm/yarn cannot honour. A root preinstall hook deletes any stray package-lock.json/yarn.lock to stop the wrong manager creeping in. |
| Docker (+ Compose v2) | current | Runs local Postgres/PostGIS and Redis via the root docker-compose.yml. Compose v2 (docker compose, no hyphen) is assumed throughout the docs. |
| PostgreSQL + PostGIS | 16 / 3.4 | The spatial database. Provided by the postgis/postgis:16-3.4 image - you do not install it on the host. PostGIS is not optional: the schema uses spatial types and indexes. |
| Redis | 7 | Queue/cache for the wind-worker. Provided by the redis:7-alpine image. Only needed if you exercise the wind-worker queue; the API server runs fine without it. |
| k6 | current | Optional - runs the load smoke test. See Verify. |
| AWS CLI v2 + Terraform | current | Only for operating the hosted environment (see Run it in production). AWS CLI v2 is required for SSO login. Not needed for local development. |
| EAS CLI | >= 14.0.0 (pinned in eas.json → cli.version) | Only for building the mobile app. Not needed for the web build or the API. |
Why the versions are pinned (and how to match them)
The pin lives in .tool-versions at the top of the checkout
(nodejs 22.16.0). Use a version manager that reads that file and Node matches
automatically - no manual switching:
# with asdfasdf install # reads .tool-versions, installs nodejs 22.16.0
# with misemise install
# with nvm (does not read .tool-versions natively)nvm install 22.16.0 && nvm use 22.16.0Then enable the pinned pnpm through Corepack rather than installing pnpm
globally - Corepack reads the packageManager field and pins the exact version
per project:
corepack enable # activates pnpm@11.0.9 from package.jsonThe supply-chain install guard (expect a delay on new packages)
pnpm-workspace.yaml sets minimumReleaseAge: 1440 - pnpm refuses to
install any npm package version published less than 1 day (1440 minutes)
ago. This is a deliberate defense: most malicious npm releases are discovered and
pulled within hours, so a one-day buffer blocks the most common supply-chain
attack vector. Do not disable it.
The practical consequence for a new maintainer: if you add a dependency that was
published in the last 24 hours, pnpm install will fail with a
release-age error rather than a network error. That is expected. Options:
- Wait out the window (preferred), or
- Add the package to the
minimumReleaseAgeExcludeallowlist only for trusted publishers (React from Meta, TypeScript from Microsoft, etc.), and remove the exclusion once the window passes.
A few ecosystems (React Native, Playwright, MapLibre) are already allowlisted
because their registry metadata omits the time field and would otherwise trip
the guard even on old, safe versions.
If your platform isn’t macOS or Linux x64/arm64
pnpm-workspace.yaml skips the precompiled native binaries for every
platform except linux-x64-gnu, linux-arm64-gnu, darwin-arm64, and
darwin-x64 (covers prod Linux + Intel/Apple-Silicon Macs). If you develop on
Windows or a BSD, native modules like esbuild, lightningcss, rollup, and
@tailwindcss/oxide will fail to resolve their binary. Unblock your platform by
removing the relevant "-" override in the overrides: block. (WSL2 on
Windows, which presents as linux-x64, works without changes and is the
recommended path.)
Accounts & access
Local development - no accounts required
For local development you need no external accounts. On first fetch the app auto-logs in and pulls live public data, so you can run the full stack - real FIRMS hotspots included - with nothing configured. External credentials are all optional and unlock specific features; every one of them degrades gracefully when unset (the feature is simply off, the server still boots):
| Credential | Env var | What it unlocks when set | Behaviour when unset |
|---|---|---|---|
| NASA FIRMS API key | NASA_FIRMS_API_KEY | Richer authenticated satellite hotspot ingest; the FIRMS scheduler auto-enables. | FIRMS ingest is off by default (FIRMS_INGEST_ENABLED defaults to false when no key). |
| Google / Microsoft OAuth | see Config reference | Third-party sign-in. | Those sign-in buttons are stubs / “coming soon”. |
| Twilio | see config | SMS one-time-code delivery. | SMS-OTP path is disabled. |
| Resend | see config | Transactional email (verify-email, password reset). | Email routes are no-ops. |
Getting a FIRMS key is free and self-serve: request one from NASA’s FIRMS “Map Key” page; it’s delivered by email. You do not need it to start - add it later only if you want authenticated ingest.
Operating the hosted environment - request access
Waking, deploying, or hibernating the production stack needs credentials you request from the project owner. There are no shared logins to hand out; each of these is granted to you individually.
1. AWS access via SSO. The hosted stack lives in a dedicated AWS account
with its own SSO directory - separate from any other project or employer
account you may already use. Request an SSO invite from the project owner. Once
invited, configure a profile named exactly firepath-admin (the ops scripts
hard-pin this name) and sign in:
aws configure sso # first time: set profile name to "firepath-admin"aws sso login --profile firepath-adminA browser opens to the Fire Path SSO start page
(<firepath-sso-directory>.awsapps.com/start). The scripts don’t rely on
AWS_PROFILE from your shell - they force firepath-admin internally and
clear any region override - precisely so a leaked profile from another terminal
can’t point Terraform at the wrong account.
Additional CLI tooling the production runbooks assume: the
session-manager-plugin (for the DB bootstrap tunnel), jq, and - for
mobile - the EAS CLI logged into the project’s Expo account (also owner-invite
only; the EAS projectId is committed in app.json).
2. Cloudflare. DNS and the web/docs/marketing deployments run on Cloudflare.
DNS for api.firepath.software is repointed on each production wake (see
Run it in production), and the docs/marketing sites
deploy to Cloudflare Pages. If you need to change DNS or push a Pages deploy,
request Cloudflare account access from the project owner. Read-only local
development never touches Cloudflare.
Quick preflight check
Before you follow Run it locally, confirm the toolchain is what the repo expects:
node --version # v22.16.0pnpm --version # 11.0.9docker compose version # Compose v2.xIf any of these disagree with the table above, fix the toolchain first - most “it doesn’t install / doesn’t build” reports trace back to a version mismatch here. See Troubleshooting for the recurring ones.