Aggregator repo combining all five ExpressCharge components as git submodules for one-clone-gets-everything development. Each submodule is also independently useful and has its own CI / release pipeline.
expresscharge/
├── web/ ← Deno + Fresh fullstack web app (admin + customer)
├── email-worker/ ← Cloudflare Workers transactional email service
├── ios/ ← Swift / iOS 26 native app
├── steve/ ← OCPP backend (fork of steve-community/steve)
└── docs/ ← Astro Starlight docs site (docs.polaris.express)
git clone --recursive git@github.com:expresscharge/monorepo.git expresscharge
cd expresscharge
make bootstrapIf you already cloned without --recursive:
make bootstrap # runs: git submodule update --init --recursivemake update # pull latest from each submodule's main, then bump pointers
make check # web + email-worker + ios lint + typecheck
make test # web + email-worker + ios test suites
make up # docker compose up integrated stack (postgres + web + sync)
make down # tear it downPer-submodule targets (web-dev, ios-build, email-worker-dev, etc.) are
documented in the Makefile.
docker-compose.yml at the root builds web/ from its Dockerfile and wires it
to a postgres container + the sync worker. The email worker runs on Cloudflare
and is not in the compose stack — for local email development,
cd email-worker && npx wrangler dev (and configure the web app's
CF_EMAIL_WORKER_URL to point at the wrangler dev URL).
Submodules are pinned to specific commits — git submodule status shows the
current pin. To bump:
make update # pulls each submodule's main
git add web email-worker ios
git commit -m "Bump submodules"CI's bump-submodules workflow does this automatically on a weekly schedule.
| Component | Repository |
|---|---|
| Web (Fresh) | https://github.com/expresscharge/web |
| Email worker | https://github.com/expresscharge/email-worker |
| iOS app | https://github.com/expresscharge/ios |
| StEvE (OCPP) | https://github.com/expresscharge/steve |
| Docs site | https://github.com/expresscharge/docs |
MIT — see LICENSE.