Goals & Philosophy
What HaloStack is for, how the monorepo is organized, and how template sync keeps downstream projects aligned.
HaloStack is a starter template that stays maintainable after it is copied. It gives a product team a working system: app shells, auth, database access, UI primitives, environment validation, notifications, telemetry hooks, jobs, AI integration, docs, tests, and deployment automation.
Why it exists
The repo removes repetitive foundation work. A new product can start from a
running stack, then replace the brand and domain model gradually. Shared
conventions are written down in AGENTS.md and .agents/rules/*.md, so humans
and coding agents make changes the same way.
Workspace shape
Apps depend on packages and config; packages do not depend on apps. That keeps shared code reusable and lets app-specific decisions stay at the edge.
Template-first maintenance
Template-worthy changes are recorded under .template/changes/next. Each entry
captures the affected areas, migration guidance, validation commands, and whether
the change is breaking for downstream projects. bun run template:changelog
turns those entries into generated changelogs, and released entries can be
compared against a child project's .template-sync.json.
The sync model is not a blind patch queue. Child projects are expected to diverge, so a downstream agent ports the intent of each change into the child repo's actual shape.
Deployment stance
The code stays host-aware but not host-entangled. Railway is the bundled deployment target:
.railway/railway.tsdeclares services, build/deploy config, healthchecks, serverless sleep settings, and the worker cron.- GitHub Actions performs production deploys with
railway upafter CI. - Railway Postgres and Redis are platform plugins.
- Cloudflare R2 provides object storage, and DNS stays manual.
- Non-production environments can run in preview mode on Railway public domains.
The deployment runbook is in Operations and
infra/railway/README.md.
Conventions that hold everywhere
- Use package subpath imports instead of deep relative imports.
- Keep TypeScript strict and avoid type escape hatches.
- Read env through
@halostack/env. - Use Biome for formatting and import organization.
- Keep each structured area's
AGENTS.mdsynchronized with its files, exports, commands, and runtime behavior.