Technology
What we work in, and how we choose
A stack list on its own says nothing. Everything below is something we have run in production and would defend in a review. The section at the bottom explains how we pick between them, which matters more than the list.
Languages
TypeScript is the default. Go and Python earn their place where the workload justifies it.
TypeScript
Default for product work, front and back
Go
Throughput sensitive services and ledgers
Python
Data pipelines and AI systems
Swift
Native iOS
Kotlin
Native Android
Rust
Edge and embedded, where it pays for itself
SQL
Treated as a first class language, not a detail
Frontend
Server rendering by default, client JavaScript only where interaction requires it.
React
With Server Components
Next.js
App Router, static by default
Remix
Where the data model suits it better
Tailwind CSS
Plus hand written design tokens
Vite
Non framework builds
Playwright
End to end testing
Storybook
Component review with clients
Backend and APIs
Contracts your partners can build against without calling you.
Node.js
With NestJS or Fastify
FastAPI
Python services
gRPC
Internal service to service
GraphQL
Where clients genuinely vary
Kafka
Event backbones
Temporal
Long running workflows
Redis
Cache, queues, rate limiting
Data
Postgres until there is a measured reason to leave it.
PostgreSQL
Default, including row level security
TimescaleDB
Time series at volume
Snowflake
Warehousing
BigQuery
Warehousing on Google Cloud
dbt
Transformation and lineage
Airflow
Orchestration
Dagster
Orchestration, asset centric
DuckDB
Local analysis and testing
Cloud and platform
Defined in code, reproducible from an empty account.
AWS
Most engagements
Azure
Enterprise and Microsoft estates
Google Cloud
Data heavy workloads
Terraform
Infrastructure as code
Pulumi
Where the team prefers a real language
Kubernetes
When the scale warrants it, not by default
GitHub Actions
CI and delivery
ArgoCD
GitOps deployment
AI engineering
Evaluation and guardrails first. The model is the easy part.
Claude API
Primary model provider
OpenAI API
Where a client is already committed
Model Context Protocol
Tool integration
LangGraph
Agent orchestration
pgvector
Retrieval inside Postgres
Qdrant
Dedicated vector search
Ragas
Retrieval evaluation
Observability and quality
Wired up with the first feature, not in a hardening phase later.
OpenTelemetry
Traces, metrics, logs
Grafana
Dashboards and alerting
Prometheus
Metrics
Sentry
Error and crash reporting
k6
Load testing at real scale
axe
Accessibility in continuous integration
Vitest
Unit and integration testing
Selection
How a stack decision actually gets made
Can your team maintain it?
The single biggest factor. A technically superior choice your engineers cannot hire for is the wrong choice. We weigh the local hiring pool before we weigh benchmarks.
What does year two cost?
Build cost is visible and maintenance cost is not. We model both, including the cost of the migration you will need if the choice turns out wrong.
Is it boring enough?
For anything load bearing we pick the option with the longest track record and the largest community. Novelty is reserved for the parts where it buys something specific.
Does it get written down?
Every significant choice becomes an architecture decision record with the options we rejected and why. In two years that file is the difference between a question and an excavation.
Working in something not listed here?
The list is what we reach for, not the limit of what we will touch. We have picked up unfamiliar stacks on inherited systems more than once. Tell us what you are running and we will be straight about whether we are the right team.
- A senior engineer reads every brief
- NDA signed before you share anything sensitive
- No sales sequence, no automated follow ups