Skip to main content

Developer Environment Reference

Canonical reference for required and optional tools, platform notes, and configuration. For step-by-step setup, see the Contributor Guide.

Required Runtimes​

ToolVersionPinned InPurpose
Node.js26.2.0.tool-versions (package.json engines allows ^24 || ^26)Angular CLI, build tooling
Bun1.3.14.tool-versions, package.json engines (>=1.3.14)Package manager, script runner
Go1.26.5.tool-versions (go.mod requires >=1.26.3)Backend compilation
Gitany—Source control, build metadata
Makeany—Build orchestration

.tool-versions is the single source of truth for exact versions — these numbers drift out of sync with it easily (this table itself was stale until 2026-07-25), so if this table and .tool-versions ever disagree, trust the file, not this page, and fix the page.

Version Management​

.tool-versions is the single source of truth for runtime versions.

ManagerInstallUsage
mise (recommended)brew install misemise install
asdfbrew install asdfasdf install
ManualPer-tool installersMatch versions in .tool-versions

build/check-versions.cjs validates versions before tests run (pretest hook).

Optional Tools​

ToolPurposeInstallWhen Needed
Docker / Podman / OrbStack / ColimaRun database containersPer-toolBackend dev with PostgreSQL
OpenSSLGenerate dev certs and encryption keysIncluded on macOS/LinuxFirst-time setup
zipRelease packagingbrew install zipmake release
swagOpenAPI doc generationgo install github.com/swaggo/swag/cmd/swag@latestAPI docs
quartoRender docs/ to standalone PDF/epub bookletsbrew install --cask quartomake build booklets — also needs Chrome (for mermaid diagrams), which Quarto auto-detects on dev machines and CI
golangci-lintGo meta-linter (staticcheck, errcheck, unused, ineffassign)golangci-lint.runmake lint, make check — lint hard-fails without it
gosecGo security scannergo install github.com/securego/gosec/v2/cmd/gosec@latestmake audit backend, make audit tests
trivyVulnerability + misconfig scanneraquasecurity/trivymake audit backend, make audit tree
govulncheckGo vuln databasego install golang.org/x/vuln/cmd/govulncheck@latestmake audit backend, make audit summary
zizmorGitHub Actions workflow SASTbrew install zizmormake audit actions
osv-scannerMulti-lockfile dependency scannerbrew install osv-scannermake audit packages, make audit licenses
gitleaksSecret scannerbrew install gitleaksmake audit secrets, make audit history
modrotArchived/deprecated dependency scannergo install github.com/norman-abramovitz/modrot@latestmake audit modrot (needs gh auth)
semgrepPattern-based SASTbrew install semgrepmake audit semgrep (manual, needs network)
codeqlDeep SAST (Go + JS/TS databases)codeql-action releasesmake audit codeql (manual — CI already runs this canonically; local run is a pre-push spot-check)
sarif-tools (sarif)Summarize SARIF filespip install sarif-toolsmake audit sarif
ghGitHub CLIcli.github.commake deps dependabot, make audit upload, make audit actions (optional, for authenticated rate limits)
Playwright browser binariesE2E test runner (the @playwright/test package itself comes via bun install)bunx playwright install chromium (add firefox/webkit for E2E_BROWSERS=firefox/webkit/all)make test e2e, make check e2e

Audit & dependency commands​

CommandPurpose
make auditDefault scanner set: frontend + website + backend + actions + packages + secrets
make audit frontendbun audit (npm advisory DB), root workspace
make audit websitebun audit (npm advisory DB), website/ workspace (tools/stb isn't covered — pre-release)
make audit backendgosec + trivy + govulncheck on both Go modules (src/jetstream, src/jetstream/api)
make audit actionszizmor SAST over .github/workflows/; ZIZMOR_FLAGS="--persona=auditor" enables the strict rule set
make audit packagesosv-scanner over every lockfile and go.mod in one pass
make audit secretsgitleaks scan of the working tree
make audit summaryHigh/moderate/low totals only — fast triage
make audit testsgosec including _test.go files, plus a #nosec suppression report
make audit treetrivy over the whole repo — covers the Dockerfiles, helm chart, and manifests under deploy/
make audit historygitleaks over the full git history (~14k commits)
make audit licensesosv-scanner dependency license report
make audit modrotmodrot archived/deprecated dependency scan (needs gh auth)
make audit semgrepsemgrep SAST via semgrep ci — uses your logged-in account's policy and dashboard if you've run semgrep login, falls back to community rules otherwise. SARIF to dist/semgrep.sarif
make audit codeqlLocal CodeQL SAST (Go + JS/TS) — manual pre-push mirror of what .github/workflows/codeql.yml runs on every push/PR. SARIF to dist/codeql-{go,js}.sarif
make audit sarifsarif-tools summary across every dist/*.sarif file, local only
make audit uploadPush dist/*.sarif to GitHub code scanning; skips codeql-*.sarif since CI already uploads those canonically. Needs push access to the repo
make outdatedList outdated direct deps in both stacks
make outdated frontendbun outdated
make outdated backendgo list -m -u all (filtered to upgradable)
make deps dependabotList open dependency PRs (requires gh auth)

Non-default audit modes​

make audit runs the six default scanners only (frontend, website, backend, actions, packages, secrets). The rest are deliberately kept off the default path:

  • tests — gosec findings inside _test.go files are advisory (test code doesn't ship), so they would add triage noise to every default run. Run it when auditing test hygiene or reviewing #nosec suppressions.
  • tree — scans the entire repository instead of src/jetstream. It exists for the deployment surface (deploy/ Dockerfiles, helm chart, CF manifests) which the backend scan doesn't reach. It is slower than the default set and its misconfig findings change rarely — run it when touching anything under deploy/ or before a release.
  • history — walks all ~14k commits (roughly 15 seconds, vs instant for the working-tree scan). Historical findings are almost entirely pre-2020 test fixtures; this is a forensic tool, not an everyday guard. The default secrets mode already catches anything you are about to commit.
  • licenses — a compliance report, not a vulnerability source. Nothing in it is actionable on a normal development day.
  • modrot — needs gh auth (GitHub GraphQL) + network, so it's a standalone extra rather than something every make audit run should depend on.
  • semgrep, codeql — both need extra tooling (a semgrep account login, the codeql CLI + query packs) and are meant to run manually on the build machine, not on every audit invocation. CodeQL in particular already runs in CI on every push/PR — the local mode exists so you can see findings before pushing, not to replace CI.
  • sarif, upload — these consume the other scanners' dist/*.sarif output; they're only meaningful after running one of the SARIF-emitting modes, so they don't belong in a default sweep either.

All audit recipes are report-only (|| true): they never fail the build, so scanner exit codes are informational. The lint/test gates are where failures block.

Container Runtimes​

Stratos does not prescribe a container runtime. Any OCI-compatible runtime works with the project's compose.yml:

RuntimePlatformNotes
Docker DesktopmacOS, Linux, WindowsMost common, licensing applies to large orgs
PodmanmacOS, Linux, WindowsRootless, daemonless, no licensing cost
OrbStackmacOSLightweight, fast, Docker-compatible
ColimamacOS, LinuxMinimal Docker-compatible on Lima VMs

Database Backends​

Stratos connects to external SQL databases. It does not bundle a database server.

BackendDATABASE_PROVIDERLocal DevProduction
SQLitesqliteDefault, zero setupNot recommended
PostgreSQLpgsqlVia containerRecommended
MySQL / MariaDBmysqlVia containerSupported

PostgreSQL 14 and later is supported — the versions the upstream lib/pq driver tests against.

Any PostgreSQL-compatible (CockroachDB, Aurora, AlloyDB) or MySQL-compatible (MariaDB, Aurora MySQL, PlanetScale) service works with existing drivers.

Database Configuration​

VariablePurposeDefault
DATABASE_PROVIDERBackend selectionsqlite
DB_HOSTHostnamelocalhost
DB_PORTPort5432 (pgsql), 3306 (mysql)
DB_USERUsername—
DB_PASSWORDPassword—
DB_DATABASE_NAMEDatabase namestratos
DB_SSL_MODETLS modedisable

Configuration​

Backend reads configuration from a 5-tier lookup chain (first match wins):

  1. Database config store — runtime settings saved after initial setup
  2. Environment variables — export KEY=value or in container env
  3. CF User-Provided Service — Cloud Foundry deployments only
  4. .env file — KEY=VALUE format in working directory
  5. /etc/secrets directory — one file per key (Kubernetes pattern)

All configuration keys work from any tier. Environment variables always override file-based settings.

This is app runtime config (ENCRYPTION_KEY below encrypts the app's own database config store) — a different concern from E2E test credentials (secrets.yaml), which have their own zero-plaintext encrypt/decrypt workflow. See Secrets Management for that.

Key Settings​

VariablePurposeRequired
ENCRYPTION_KEY256-bit hex encryption keyYes
CONSOLE_PROXY_TLS_ADDRESSListen addressNo (default :5443)
AUTH_ENDPOINT_TYPElocal or remoteNo (default remote)
SESSION_STORE_SECRETCookie encryptionNo (has default)
LOG_LEVELdebug, info, warn, errorNo
SKIP_SSL_VALIDATIONSkip TLS checks for CF endpointsNo

See src/jetstream/config.example for all available settings with descriptions.

Ports​

ServiceDefaultOverride Variable
Frontend dev server5440FRONTEND_PORT
Backend (jetstream)5443BACKEND_PORT
E2E frontend5540E2E_FRONTEND_PORT
E2E backend5543E2E_BACKEND_PORT

An e2e run still reads FRONTEND_PORT and BACKEND_PORT when the E2E_ names are unset, for one release only.

IDE Support​

No IDE is prescribed. Stratos works with any editor that supports LSP.

EditorRecommended Extensions
VS CodeAngular Language Service, Go (gopls)
WebStorm / GoLandBuilt-in Angular + Go support
Neovimangular-language-server + gopls via LSP

Angular Language Service is included in devDependencies for template type-checking in any IDE.

Supported Platforms​

Developer build platforms​

OSArchNotes
macOSarm64 (Apple Silicon)Primary dev platform
macOSamd64 (Intel)Supported
Linuxamd64CI and dev
Linuxarm64Supported

Target platforms (cross-compilation)​

OSArchUse case
linuxamd64Cloud Foundry, Docker, most servers
linuxarm64ARM servers, Graviton
darwinamd64macOS Intel
darwinarm64macOS Apple Silicon
windowsamd64Windows servers
windowsarm64Windows ARM

Platform detection uses uname -s | tr '[:upper:]' '[:lower:]' for OS and normalizes architecture (x86_64 → amd64, aarch64 → arm64) to match Go's GOOS/GOARCH conventions. Override with PLATFORM=os/arch.

Cross-compilation is host-arch-independent for the standard build (CGO_ENABLED=0, no C cross-compiler involved) — an arm64 machine builds any of the six combinations above exactly as an amd64 machine does, and vice versa. See Development in build-and-packaging.md for how PLATFORM interacts with make build vs make stage.

Platform-specific notes​

macOS​

  • Xcode Command Line Tools required (xcode-select --install) for Make and Git
  • GNU Make 3.81+ required (ships with Xcode CLI tools)
  • openssl from Homebrew recommended over LibreSSL for cert generation
  • Apple Silicon (arm64) is the native build target; use PLATFORM=linux/amd64 for CF release builds

Linux​

  • build-essential package provides Make and GCC
  • SQLite no longer needs GCC/cgo — the backend uses the pure-Go ncruces/go-sqlite3 driver, so standard CGO_ENABLED=0 builds work

CI/CD​

GitHub Actions workflows:

WorkflowFileTrigger
Frontend tests.github/workflows/frontend_tests.ymlPush/PR to develop/main
Backend tests.github/workflows/backend_tests.ymlPush/PR to develop/main
Release + all-in-one image.github/workflows/release.ymlVersion tag

Known CI Drift​

CI workflows use outdated tool versions. Tracked in FWT-840.

WorkflowComponentCI VersionShould Be
frontend_testsNode.js1624
backend_testsGo1.21.01.24.2
prNode.js2424 (correct)
prGo1.211.24.2
releaseNode.js2424 (correct)
releaseGo1.211.24.2
AllPackage managernpmbun

CF Release Build Process​

make release cf packages the app for CF deployment but does not build. The backend binary must be pre-built for the target Linux platform.

Build naming​

CommandOutputPurpose
make builddist/bin/jetstream-{os}-{arch} (all platforms)Frontend + all backend platforms
make build backend PLATFORM=linux/amd64dist/bin/jetstreamSingle backend platform
make dev backenddist/bin/jetstreamHost platform only (development)

CF release workflow​

# 1. Build and package in one command (cf modifier forces linux/amd64):
make build release cf

# Or step by step:
make build cf
make release cf

# 3. Deploy
cf target -o system -s stratos
cf push -f dist/cf-package/manifest.yml -p dist/stratos-cf-<version>.zip

make release cf validates that dist/bin/jetstream is a Linux ELF binary before packaging. If it's a macOS or Windows binary, the packaging fails with a clear error.

On CI (Linux)​

make build cf produces a Linux binary natively. Or make build release cf to build and package in one step.

On macOS​

The cf modifier automatically sets PLATFORM=linux/amd64:

make build release cf # linux/amd64 (default)
make build release cf PLATFORM=linux/arm64 # ARM CF deployments

Further Reading​