Aspire technology stack โ defaults for new projects
Context
New Aspire projects historically picked their own stack (Next.js + Prisma, NestJS + TypeORM, Django + DRF, etc.), which fragmented the engineering surface and made cross-project hiring/maintenance harder. As of 2026-05-31, there is a single default starting stack for all new apps.
This is a standing instruction: every new Aspire/Zinga/Alby/Goldroom app should start from this stack until there is a clearly better option. If a project uses something else, record the reason as an ADR/spec note before implementation so future agents and humans can see the trade-off.
Detail
Default app stack
| Layer | Default | Implementation note |
|---|---|---|
| Frontend | SvelteKit | SSR-first app shell with small client bundles; use the Svelte ecosystem for UI/BFF glue. |
| Backend API | Go | Prefer a small HTTP service boundary; Echo is acceptable where a framework is useful. |
| Backend ORM | GORM | Default relational mapping layer for Go services. Keep raw SQL for hot paths or complex reporting. |
| Scripting / BFF | Node.js | Use for SvelteKit integration, prototypes, CLIs, and glue code rather than core long-lived APIs. |
| Primary database | PostgreSQL | Use JSONB and pgvector where useful; avoid introducing another primary database. |
| Node/TS ORM | Prisma | Use when a TypeScript service or SvelteKit server code needs typed DB access. |
| Cache / queue | Redis | Sessions, rate limits, real-time state, background handoff, and ephemeral workflow state. |
| Object storage | MinIO | Self-hosted S3-compatible storage for user uploads, generated media, AI datasets, and cached assets. |
| Model gateway | LiteLLM via Aspire LLM Gateway | All app LLM traffic goes through the gateway unless an ADR says otherwise. |
| Local inference | Local models when hardware exists | Defer until workstation-class GPU capacity is available; use gateway/cloud fallbacks meanwhile. |
| TTS | ElevenLabs | Current default for voice response synthesis. Cache generated audio in MinIO where practical. |
| STT | Provider-specific, behind app boundary | Twilio speech gather is acceptable for telephony apps; revisit per channel. |
| VCS / CI | Self-hosted GitLab | Prefer decoupled repositories and independent pipelines per service. |
| Production deploy | GitLab-built artifacts on Coolify now, Kubernetes target | GitLab CI builds/scans/promotes images or artifacts; Coolify runs them as the practical deployment layer. Kubernetes is the target when app scale warrants it. |
| Proxy / ingress | Nginx target | Current path may still be Cloudflare -> Coolify/Traefik. Move toward Nginx where infrastructure changes justify it. |
Repository and deployment default
- New apps should be decoupled by service: at minimum
app-webandapp-apiwhen the backend is meaningful enough to scale or deploy independently. - GitLab CI should build deployable artifacts/images and push immutable tags. Coolify should pull/run those artifacts using
dockerimageapps where possible; Coolify-side Dockerfile builds are a legacy/fallback path. - Keep infrastructure choices version-controlled where possible. For Coolify apps, document app UUIDs, env-var contracts, health checks, domains, deploy hooks, registry images, immutable tag policy, smoke tests, and rollback tags in the project spec or deploy inventory.
- Prefer MinIO for binary/data storage from day one rather than waiting for uploads or generated media to sprawl into local disk or third-party buckets.
- Prefer Redis for cross-request state from day one. Do not rely on in-process Maps for sessions, call state, queues, or rate limits in production services.
- Put LLM access behind the Aspire LLM Gateway/LiteLLM abstraction even if the first implementation only calls one upstream provider.
Existing apps that stay on legacy stacks
| App | Stack | Notes |
|---|---|---|
zinga-* (PMS, Booking, CM, Kitchen, Procure, Ledgr, Pay) | Next.js + Prisma | Already shipped, don't refactor |
alby-studio | Next.js + custom auth | Already shipped |
| Aspire Staff Portal / Hub | Next.js + NextAuth + Prisma (in Turborepo) | Already shipped, integrates with new stack via OIDC |
| Knowledge OS engine | Python (FastAPI + FastMCP) | Async ML workloads benefit from Python |
| WordPress merchant storefronts (Alby Place, Six Degrees, etc.) | WordPress + WooCommerce + Elementor | Merchant tier; not Aspire-engineered |
Product-specific exceptions
- WordPress merchant-storefront products stay on WordPress Multisite + WooCommerce + Elementor. Do not propose SvelteKit/Go rewrites for those storefronts unless the product direction changes.
- WordPress content sites are not exempt from Git when custom behavior exists. Put custom themes, child themes, custom plugins, MU plugins, production Code Snippets, Elementor/ACF config, and deploy manifests in Git. Keep uploads, customer/order data, WP core, third-party plugin packages, caches, backups, and secrets out of Git.
- Existing shipped Next.js/Prisma apps should not be rewritten only to satisfy this standard. Migrate when there is a real product, scaling, hiring, or maintenance reason.
- Python remains valid for ML-heavy, data-science, MCP, OCR, and automation modules where the ecosystem materially beats Go.
Excluded
- MongoDB (use Postgres JSONB instead)
- MySQL/MariaDB (use Postgres)
- Firebase (vendor lock; use self-hosted Postgres + Redis + MinIO)
- Vercel/Netlify hosting (use Coolify for ops parity)
- GitHub as primary remote (use self-hosted GitLab)
- Direct provider SDK sprawl for AI/storage/payment primitives (use Aspire LLM Gateway, MinIO, and payment gateway abstractions where available)
MCP-friendly tooling
Where possible, prefer apps with official MCP servers (Coolify, GitLab, n8n, Odoo, Stripe, Xero) so agents can drive them programmatically without ad-hoc scripts.
Migration priority for legacy apps
When touching legacy apps, prefer incremental alignment before rewrites:
- Add Redis for sessions, rate limits, queues, and real-time/call state.
- Add MinIO for user media, generated media, cached TTS, and AI datasets.
- Route model calls through LiteLLM/Aspire LLM Gateway.
- Move deploys to GitLab-built immutable images/artifacts promoted through staging and prod.
- Add or update the project deploy inventory, including Coolify UUIDs, registry image, health checks, smoke tests, and rollback tag.
- Split tightly coupled monorepos only when independent deploy cycles or ownership boundaries justify it.
- Consider SvelteKit + Go rewrites only when the app is being substantially rebuilt anyway.
Revisit
Stack defaults reviewed quarterly. Last review: 2026-06-04.
Related
- use-postgresql-by-default
- aspire-llm-gateway-only-egress
- gitlab-self-hosted-not-github
- minio-storage-per-app