
Our Tech Stack & Why We Chose It
We optimize for developer speed, operational reliability, and security by design. Our default stack:
- Backend: NestJS (TypeScript)
- Database: PostgreSQL (managed on Azure)
- Caching & Queues: Redis (Azure Cache for Redis)
- Web: React (Vite or Next.js when SSR/SEO is needed)
- Mobile: React Native (Expo first)
- Cloud: Microsoft Azure (Container Apps/AKS, Key Vault, App Gateway/Front Door, Application Insights)
Architecture at a glance
- Clean, modular services in NestJS (monolith-first or modular monolith → services when needed).
- PostgreSQL as the system of record; Redis for read-through cache, rate limits, ephemeral sessions, and BullMQ queues.
- HTTP APIs (REST/OpenAPI) and background workers; webhooks for integrations.
- React web app + React Native (Expo) mobile from a monorepo (shared UI/types).
- Azure: Containerized workloads, Key Vault for secrets, Application Insights + OpenTelemetry.
Backend — NestJS
Why NestJS? Opinionated structure, DI, testability, and first-class TypeScript.
Database — PostgreSQL
Why Postgres? Reliability, strong SQL + JSONB, great extensions (pgcrypto, trigram).
Azure choice
- Azure Database for PostgreSQL – Flexible Server, zone-redundant HA where required.
Data access
- Sequelize with explicit migrations and models
- Use of idempotent migrations, forward-only; verify in staging.
Caching & Queues — Redis
Use cases
- Read-through cache for hot queries (TTL 5–30 min).
- Idempotency keys, rate limits, ephemeral sessions.
- BullMQ queues for background jobs (emails, webhooks, ETL), with backoff/retry.
Web — React
Why React? Ecosystem depth; smooth handoff to React Native.
- Vite for SPAs; Next.js when SSR/SEO or edge rendering helps.
- UI: headless components or design system.
- State: Zustand with tanstack React Query; forms via React Hook Form + Zod.
Mobile — React Native (Expo)
Why Expo? Rapid iteration and great device APIs.
- Offline-first with SQLite where necessary
- Shared logic with web via monorepo libs (types, validation, API SDK).
Cloud — Azure
Compute
- Azure Container Apps (simple) or AKS (at scale).
- Background workers as separate containers; autoscale on queue length or CPU.
Networking & delivery
- Azure Front Door or Application Gateway for WAF + TLS; CDN for assets.
Secrets & identity
- Azure Key Vault (managed identities for access).
- Azure AD / Entra ID or B2C for auth; JWTs to apps; RBAC in services.
Data & storage
- Azure PostgreSQL Flexible Server, Azure Cache for Redis, Blob Storage for uploads; lifecycle rules for retention.
Observability
- Application Insights with Prometheus export (traces, logs, metrics).
- Logging with Loki; streamed to Grafana
Tooling
- ESLint/Prettier shared config
- Zod schemas shared across API and clients (type-safe DTOs).
Golden Defaults
PostgreSQL
uuid
primary keys; timestamps with time zone.- Sequelize migrations; never hot-edit prod.
- Indices for foreign keys, unique business keys; partial indexes for common filters.
Redis
- TTL on all cache entries; never store PII.
- Separate DBs or prefixes for cache vs. queues.
- Dead-letter queues for jobs; alert on retries > N.
NestJS
- Global validation pipe (Zod or class-validator), strict DTOs.
- Central error filter → problem+json; consistent error codes.
- Feature flags (configurable via Azure App Configuration or env).
React / RN
- Error boundaries; analytics with consent; i18n scaffolding.
- API SDK generated from OpenAPI (type-safe).
- Form validation with shared Zod schemas.
Frequently asked Questions
Can we run without AKS?
Yes. We default to Azure Container Apps for simpler ops; AKS for high scale/custom needs.
Do you force AI into projects?
No. We add AI only when it outperforms classic logic on speed/quality/cost.
Can our team operate the system?
Yes. We deliver dashboards, runbooks, and training; ops handover is part of the project.