The Dev Stack We Ship in 2026: Why This Combo Works
We've shipped 16 industry-specific CRMs, 49 production AI agent specialties, and dozens of bespoke systems over the last few years. Every founder asks the same question during discovery: "What tech stack will you use?"
Here's the honest answer. No hand-waving about "best practices" or "cutting-edge innovation." Just the stack we bet on in 2026, the tradeoffs we've accepted, and why this particular combo lets us ship fast without accumulating technical debt.
The Core: Next.js 15 + TypeScript + Tailwind
Next.js 15 is our frontend and backend framework. We use the App Router exclusively now — yes, it was rocky in 13 and 14, but the React Server Components model has matured. For us, the win is simple: we can co-locate data fetching with UI components, ship less JavaScript to the client, and still have full control when we need client-side interactivity.
Server Actions replace most of our API routes. When you're building a CRM like HotelDesk or LegalEase, you're handling dozens of forms, mutations, and table operations. Server Actions let us write these handlers right next to the form component, validate with Zod on the server, and get type safety end-to-end. No separate /api folder. No context switching.
TypeScript is non-negotiable. We run strict mode ("strict": true in tsconfig.json). The upfront cost is real — you spend more time getting types right — but we've eliminated an entire class of runtime bugs. When you're maintaining 16 different codebases, consistency matters more than speed. TypeScript enforces that consistency.
Tailwind CSS for styling. We tried CSS Modules, Styled Components, and even plain CSS. Tailwind won because:
- Design system constraints are built in (spacing scale, color palette)
- No context switching between files
- Purging unused styles is automatic
- Onboarding new devs is faster — everyone reads the same utility classes
We extend the default config for brand colors and a few custom utilities, but 90% of our styling uses stock Tailwind. That consistency shows up in our services delivery speed.
Database: PostgreSQL + Supabase
We standardised on PostgreSQL years ago. It's boring. It works. Row-level security, JSONB columns, full-text search, and GIS extensions mean we rarely need to bolt on another service.
Supabase sits on top. It gives us:
- Instant REST and GraphQL APIs (we rarely use these, but nice to have)
- Real-time subscriptions via WebSockets
- Built-in auth with social providers, magic links, and SAML
- Storage buckets for user uploads
- Edge Functions for serverless compute
The real win: Row-level Security policies. We define security rules at the database level, not in application code. Every CRM we ship has multi-tenant isolation enforced by Postgres policies. A user from Company A literally cannot query Company B's rows, even if they craft a malicious request.
Example RLS policy from our PharmaCare CRM:
CREATE POLICY "Users can only access their pharmacy's inventory"
ON inventory
FOR SELECT
USING (pharmacy_id = auth.jwt() ->> 'pharmacy_id');
This beats writing authorization checks in every API handler. We write the policy once, and it's enforced by the database engine itself.
We use Prisma as the ORM. Type-safe queries, automatic migrations, and a schema file that serves as documentation. The Prisma Studio GUI is handy for debugging production data without writing raw SQL.
AI Layer: OpenAI + LangChain + Pinecone
Our 49 AI agent specialties run on this stack:
- OpenAI API (GPT-4o and GPT-4o-mini) for language understanding and generation
- LangChain for orchestration, prompt templates, and agent loops
- Pinecone for vector search (embeddings storage)
We considered open-source models (Llama 3, Mixtral) but the operational overhead wasn't worth it. OpenAI's API is reliable, fast, and the pricing works for our use cases. We pay $0.002 per 1K tokens on GPT-4o-mini, which covers 80% of our agent workloads.
LangChain gets criticism for being too abstraction-heavy. Fair point. But when you're building 49 different agent types — from customer support bots to inventory forecasting agents — having reusable chains and memory implementations saves weeks. We don't use every LangChain feature. We use:
- Prompt templates with variables
- The ReAct agent pattern for tool use
- Conversation memory with Postgres as the backing store
Pinecone hosts our vector embeddings. We embed customer documents, product catalogs, and historical support tickets. When a user asks a question, we do a semantic search against these embeddings and feed the relevant context into the LLM. It's straightforward, and Pinecone's pricing is predictable (unlike some alternatives where egress fees surprise you).
Deployment: Vercel + Railway + GitHub Actions
We deploy Next.js apps to Vercel. It's the path of least resistance. Push to main, and it's live in 30 seconds. Edge caching, automatic HTTPS, and preview deployments for every PR. The Hobby tier is free; the Pro tier ($20/month per project) gets you better analytics and support.
Postgres databases run on Railway. We tried RDS, Digital Ocean Managed Databases, and self-hosting. Railway won on developer experience. You provision a Postgres instance in 60 seconds, connection strings are auto-injected as environment variables, and backups are automatic. Pricing is usage-based (you pay for resources consumed), which aligns with how we bill clients.
GitHub Actions handles CI/CD for everything else:
- Run Playwright tests on PRs
- Type-check with
tsc --noEmit - Lint with ESLint
- Deploy background workers (BullMQ jobs) to Railway
- Run database migrations via Prisma
Our typical Action workflow takes 3-4 minutes. We cache node_modules and Playwright browsers to keep it fast.
The Pieces We Skipped (And Why)
Microservices: We're a small team shipping for SMBs. Monorepos with shared packages give us code reuse without the operational overhead of service meshes and inter-service communication.
Kubernetes: Too much operational complexity for our scale. Railway gives us containerisation without writing YAML.
GraphQL: We tried it. The client-side caching story (Apollo, Relay) never clicked for our use cases. REST + React Query is simpler and easier to debug.
NoSQL databases: Postgres with JSONB columns covers 95% of the "flexible schema" use cases. We don't want to manage two database paradigms.
Why This Combo Lets Us Ship Fast
The stack isn't exotic. That's the point. Every piece is:
- Well-documented: Onboarding a new dev takes days, not weeks
- Type-safe: Fewer runtime surprises, especially across the DB → API → UI boundary
- Operationally simple: Managed services over self-hosting, every time
- Composable: We reuse components, database schemas, and AI chains across projects
When a remote-first logistics company needs a CargoTrack CRM and a Riyadh hotel group needs a booking engine, we're not rewriting infrastructure. We're composing primitives we've battle-tested across 16 products.
That's the stack we're betting on in 2026. Not because it's trendy. Because it works.