Skip to content

Tech stack

The tools we actually ship with.

Every tool on this page is one we have used in production, at scale, more than once. We do not collect technologies — we pick them because they work, and we are opinionated about the rest.

If a tech you need is not here, tell us what you are building. We have picked up new stacks quickly when the product and team needs were clear.

25+ technologies in production · 7 capability areas · Opinionated, not exhaustive

Selection process

How we pick

We apply four tests before adopting anything into the stack.

1

Has it earned it?

New tools are on probation. A tool earns a permanent place after surviving multiple production engagements without becoming a liability.

2

Can we operate it at 3 a.m.?

When systems fail, operability decides outcomes. We prefer boring, observable systems over clever, opaque ones.

3

Does it compose?

Specialized tools that connect cleanly beat monoliths that claim to do everything. Composition wins over accidental complexity.

4

Is the community real?

Active maintenance, answered issues, and honest docs matter more than launch hype. We avoid stacks with weak production signals.

What this means in practice
If we recommend a tool to a client, we have lived with it long enough to know where it breaks. Every yes on this page is backed by real production scar tissue.

Frontend

The user-facing layer. We build everything from marketing sites to complex internal dashboards and customer SaaS apps. React for complex stateful UI, Next.js for production web, and plain HTML/CSS/JS when simpler genuinely wins.

React logo

React

Primary choice for: complex, stateful UIs - admin dashboards, multi-step workflows, and internal tools.

Why we use it

  • Mature ecosystem with proven patterns and hiring depth.
  • Component model maps cleanly to how complex UI is designed.
  • Modern React primitives keep large interfaces maintainable.
  • Excellent long-term maintainability for evolving products.

Where it shines in our work: Used in our analytics platform for a query builder with hundreds of composable filter states. Read Consumer app analytics platform

When we do not reach for it: We do not default to React for simple marketing pages with minimal interactivity. Plain HTML/CSS/JS ships faster and loads lighter.

Next.js logo

Next.js

Primary choice for: production web apps that need server rendering, SEO, and strict performance budgets.

Why we use it

  • App Router with server components and streaming works well for modern app architecture.
  • TypeScript, routing, middleware, and image optimization are first-class.
  • Can deploy on Vercel or self-host on containers without changing core architecture.
  • Great default for sites that need both product UX and marketing SEO.

Where it shines in our work: Powers this site and our globally personalized media homepage implementation. Read Media edge personalization

The honest limitations: Framework churn is real. We isolate framework-specific code so business logic remains portable.

TypeScript logo

TypeScript

Primary choice for: every non-trivial frontend or Node.js project.

Why we use it

  • Prevents a large class of runtime type bugs before deployment.
  • Refactors remain safe as codebases and teams scale.
  • Editor tooling and autocomplete materially improve delivery speed.

When we do not reach for it: We occasionally skip TypeScript for tiny throwaway scripts or prototypes where setup overhead outweighs value.

Tailwind CSS logo

Tailwind CSS

Primary choice for: new interfaces that need speed, consistency, and maintainable design tokens.

Why we use it

  • Utility-first workflow keeps styles close to component logic.
  • Design tokens centralize consistency in one predictable layer.
  • JIT output keeps production bundles lean.
  • Works cleanly with accessible primitives like Radix and shadcn/ui.

The honest limitations: Class-heavy markup can feel noisy, but locality and consistency usually outweigh the tradeoff in product teams.

shadcn/ui logo

shadcn/ui

Primary choice for: accessible UI primitives in React apps without vendor lock-in.

Why we use it

  • Components are copied into your repo so you own them fully.
  • Built on Radix primitives with strong keyboard and ARIA behavior.
  • Simple to customize without fighting heavy theme systems.
Vanilla HTML/CSS/JS logo

Vanilla HTML/CSS/JS

Primary choice for: marketing pages, small brochure sites, and lightweight campaign landing pages.

Why we use it

  • Fastest path to first paint with minimal runtime overhead.
  • No framework migration tax later.
  • Easy for any engineer to maintain.

Not Used

What we avoid in Frontend

Angular (for net-new work)

Solid framework, but steeper learning curve and a smaller hiring pool for our typical client contexts. We support it when clients already run it.

Vue / Svelte / Solid by default

All technically strong. We bias toward React due to ecosystem scale, library maturity, and hiring leverage unless there is a specific reason not to.

Redux (new projects)

Modern React state tools cover most use cases with less ceremony and lower cognitive overhead.

Trend-chasing rewrites

Rewriting frontend stacks repeatedly for hype burns roadmaps and creates avoidable product risk.

Backend

We pick languages by workload, not preference. Go for throughput and networking, Python for ML/data workloads, and Java for established JVM ecosystems and enterprise integrations.

Go logo

Go

Primary choice for: APIs, CLIs, high-throughput services, and data pipelines.

Why we use it

  • Compiles to a single binary with small, fast deployment artifacts.
  • Concurrency model is excellent for network-heavy systems.
  • Standard library is production-grade for common service workloads.
  • Strong static typing with low ceremony.

Where it shines in our work: Used for ingestion in a real-time analytics system processing 100k events/second on a single node. Read SaaS real-time analytics pipeline

The honest limitations: Verbose explicit error handling and younger generics ergonomics versus some newer typed languages.

Python logo

Python

Primary choice for: data engineering, ML/AI workloads, analytics scripts, and fast prototyping.

Why we use it

  • ML and data ecosystem is unmatched (PyTorch, Pandas, Polars, dbt tooling).
  • Readable for mixed engineering and data-science teams.
  • Excellent as a glue language across services and platforms.

The honest limitations: For sustained high-throughput API workloads, we usually move core serving paths to Go.

Java logo

Java

Primary choice for: JVM-heavy ecosystems, stream processing, and enterprise integration workloads.

Why we use it

  • Mature tooling and strong long-term compatibility guarantees.
  • Excellent ecosystem around Kafka, Flink, and enterprise middleware.
  • Modern Java (17+) significantly improved developer ergonomics.

When we do not reach for it: If there is no JVM requirement for a new service, we usually prefer Go for lower operational complexity.

Not Used

What we avoid in Backend

Node.js for CPU-bound services

Node excels at I/O-heavy workloads, but CPU-intensive services are usually cleaner and safer in Go.

Ruby (new projects)

Still productive, but performance profile and hiring trends are less favorable for our target workloads.

PHP (new services)

Fine for legacy support, but not a default for new backend service architecture.

Microservices by default

Modular monoliths are often the better starting point. Premature service splits increase complexity before they add value.

Databases

Database choices are high-leverage and painful to reverse. We default deliberately: Postgres for operational data, ClickHouse for analytics, MongoDB where document shape truly wins, and MySQL when existing deployments require it.

PostgreSQL logo

PostgreSQL

Primary choice for: operational databases and the default choice for most application workloads.

Why we use it

  • Correct default for relational data with powerful extensions.
  • Mature replication, backup, and recovery capabilities.
  • Strong ecosystem across managed providers and tooling.
  • Excellent foundation for transactional systems and SQL analytics.

Where it shines in our work: Used broadly in our SaaS builds and in cloud-cost optimization work for large event tables. Read E-commerce cloud cost reduction

ClickHouse logo

ClickHouse

Primary choice for: analytical workloads, event data, and large time-series query workloads.

Why we use it

  • Columnar compression yields major storage and query efficiency gains.
  • Excellent performance on scans over billions of rows.
  • Materialized views and horizontal scale fit modern analytics workloads.
  • Strong managed ecosystem with production-grade options.

Where it shines in our work: Used for billion-event analytics with sub-second dashboard querying. Read Consumer app analytics platform

When we do not reach for it: Not the default for small datasets or frequent row-level updates where Postgres remains simpler and sufficient.

MySQL logo

MySQL

Primary choice for: existing MySQL-heavy environments and compatibility-driven workloads.

Why we use it

  • Battle-tested engine with broad ecosystem support.
  • Common in legacy ecommerce and CMS-adjacent systems.
  • Strong option where teams are deeply MySQL fluent.

When we do not reach for it: For greenfield SaaS systems, we typically choose Postgres for extension ecosystem and operational tooling.

MongoDB logo

MongoDB

Primary choice for: document-shaped data with highly variable attributes and flexible schema requirements.

Why we use it

  • Natural fit for JSON-heavy document models.
  • Managed Atlas offering is operationally strong.
  • Horizontal scale model is straightforward.

The honest limitations: Used less often than hype suggests. Many use cases fit Postgres plus JSONB with stronger relational guarantees.

Not Used

What we avoid in Databases

DynamoDB by default

Powerful at specific scale profiles, but query flexibility and operational ergonomics are often worse for typical product workloads.

NoSQL because expected scale

Most teams benefit from starting on Postgres and migrating only when proven workload constraints demand it.

Specialty databases for tiny problems

A dedicated graph or time-series system for small workloads adds operational drag with little upside.

Infrastructure & Streaming

This is the plumbing that keeps data moving and services reliable. We prefer managed platforms when they reduce operational burden, and self-host only when control or economics require it.

Apache Kafka logo

Apache Kafka

Primary choice for: event streaming, async service communication, and CDC pipelines.

Why we use it

  • Default event backbone for modern streaming architectures.
  • Durable partition model with strong horizontal scalability.
  • Deep ecosystem via Kafka Connect, Streams, and managed services.

Where it shines in our work: Backbone of our high-volume real-time analytics pipelines with sub-second latency. Read SaaS real-time analytics pipeline

Docker logo

Docker

Primary choice for: local development, CI artifact packaging, and predictable deployment handoff.

Why we use it

  • Portable artifact model from laptop to production.
  • Mature tooling and ecosystem support across every cloud.
  • Fast onboarding with reproducible multi-service local environments.
Kubernetes logo

Kubernetes

Primary choice for: production orchestration when service count and operational needs justify it.

Why we use it

  • Strong portable abstraction across cloud providers.
  • Rich ecosystem of controllers and operational tooling.
  • Reliable model for scaling and standardizing runtime environments.

When we do not reach for it: Not a default for small teams or MVPs. Simpler platforms are usually better until scale proves otherwise.

AWS

Primary choice for: primary cloud platform for most client environments.

Why we use it

  • Deep service catalog and mature operational ecosystem.
  • Strong documentation and large hiring pool familiarity.
  • Excellent managed offerings for compute, storage, and data services.

Where it shines in our work: Used in a cloud-cost transformation that reduced spend by 62% in eight weeks. Read E-commerce cloud cost reduction

GCP logo

GCP

Primary choice for: teams already on GCP and analytics/ML workloads where BigQuery or Vertex AI are a fit.

Why we use it

  • BigQuery remains excellent for ad-hoc analytics at scale.
  • Cloud Run is one of the cleanest container serverless platforms.
  • Strong option for specific ML and data workloads.

When we do not reach for it: We avoid unnecessary multi-cloud complexity when a team is already deeply invested in AWS.

Not Used

What we avoid in Infrastructure & Streaming

Azure (unless client-standard)

We support Azure where it is already strategic, but rarely choose it first for net-new engagements.

Serverless everywhere

Great for event-driven glue, poor default for steady high-throughput compute or long-lived processing.

Service mesh without need

Meshes solve real problems at scale, but add significant operational overhead for smaller service fleets.

Multi-cloud as default posture

Complexity cost is usually higher than lock-in risk reduction. One primary cloud is usually the pragmatic choice.

Mobile

Native where performance and platform depth matter. Cross-platform where delivery speed and shared logic matter more. We ship both, based on product requirements.

Swift logo

Swift

Primary choice for: iOS-native apps needing platform depth, performance, and high-fidelity UX.

Why we use it

  • Strong type system and modern language ergonomics.
  • Immediate access to new iOS APIs and platform capabilities.
  • Excellent tooling via Xcode and Instruments.
Kotlin logo

Kotlin

Primary choice for: Android-native apps with complex UI or deep platform integrations.

Why we use it

  • Strict upgrade over Java for modern Android development.
  • Jetpack Compose is production-ready and efficient.
  • Coroutines simplify robust async and concurrency flows.
React Native logo

React Native

Primary choice for: cross-platform apps where shared business logic materially speeds delivery.

Why we use it

  • High code sharing across iOS and Android reduces duplicated effort.
  • React mental model lets web teams contribute effectively.
  • Mature ecosystem with proven production use.

The honest limitations: Heavy gesture, camera, or animation workloads can hit native bridge limits and require platform-specific modules.

Flutter logo

Flutter

Primary choice for: custom UI-heavy applications requiring consistent rendering across platforms.

Why we use it

  • Single rendering engine gives highly consistent cross-platform output.
  • Strong hot reload and productive development loop.
  • Good option for animation-rich and brand-heavy interfaces.

When we do not reach for it: When strict platform-native look and feel is the top priority, native Swift/Kotlin remains the default.

Not Used

What we avoid in Mobile

Ionic / Cordova wrappers

For modern app quality targets, React Native and Flutter consistently outperform legacy hybrid wrappers.

Xamarin / MAUI by default

Useful in specific .NET-centric teams, but generally less compelling than React Native or Flutter for new product work.

Write-once as dogma

Cross-platform saves time, but some platform-specific code is often required for polished production outcomes.

AI & LLM Tooling

We build production AI systems, not demos. That means we optimize for evaluation quality, observability, reliability, and cost - not just prompt novelty.

Anthropic Claude logo

Anthropic Claude

Primary choice for: primary LLM choice for most chat, RAG, extraction, and classification workloads.

Why we use it

  • Strong instruction-following and long-context behavior.
  • Reliable multi-turn reasoning quality in production scenarios.
  • Clean API ergonomics for robust backend integration.

Where it shines in our work: Core model in legal-tech RAG systems with strict source attribution requirements. Read Legaltech RAG for regulatory docs

OpenAI / GPT logo

OpenAI / GPT

Primary choice for: secondary provider when tool-use patterns or client constraints favor OpenAI.

Why we use it

  • Mature tooling ecosystem and broad platform support.
  • Useful for multi-provider routing strategies.
  • Strong choice in client environments already standardized on OpenAI.
Open-source LLMs logo

Open-source LLMs

Primary choice for: cost-sensitive, sovereign, or specialized fine-tune workloads.

Why we use it

  • Can reduce inference costs dramatically at stable scale.
  • Supports stricter data residency and compliance requirements.
  • LoRA and related tuning workflows enable domain-specific optimization.

The honest limitations: Model operations complexity increases quickly. Serving and evaluation discipline are mandatory.

pgvector / Qdrant / Weaviate logo

pgvector / Qdrant / Weaviate

Primary choice for: vector storage for RAG and semantic search workloads.

Why we use it

  • pgvector is an excellent default when Postgres already exists.
  • Qdrant and Weaviate offer scalable options as vector needs grow.
  • Lets retrieval architecture match scale and latency requirements.
Langfuse / Helicone logo

Langfuse / Helicone

Primary choice for: LLM observability for tracing, cost tracking, and production diagnostics.

Why we use it

  • Token-level cost and latency visibility is essential in LLM systems.
  • Prompt and completion traces speed production debugging.
  • Supports grounded iteration through measurable evaluation loops.
dbt logo

dbt

Primary choice for: transforming raw event streams into analytics-ready data models.

Why we use it

  • SQL-first workflow for engineers and analysts together.
  • Built-in testing, docs, and lineage for durable analytics pipelines.
  • Integrates cleanly with modern warehouse and lakehouse stacks.

Not Used

What we avoid in AI & LLM Tooling

LangChain in production by default

Useful for prototyping, but abstraction layers can hide core behavior and complicate production debugging.

Chasing every new model release

Model swaps require prompt retuning and regression testing; we change only for meaningful quality/cost gains.

Fine-tuning as first resort

Prompting and retrieval improvements usually deliver better ROI before training complexity is justified.

AI-first for deterministic problems

If SQL or deterministic logic solves it reliably, that is usually the better product and operations decision.

Don't see your stack?

We pick up new tools when the project calls for it. If your stack is not listed, that is not a blocker. Share what you are building and we will tell you quickly if we are the right fit.