Choosing the Right Tech Stack for a Custom Web Application
Picking the stack for a custom web app affects hiring, performance, cost and longevity for years. Here's how we choose - with the actual reasoning we use with clients.
The tech stack decision is the most consequential one made early in a custom application project, and the one made with the least information. The developer wants what they know. The CTO wants what’s trendy. The CEO wants whatever’s cheapest. None of those are great selection criteria.
Here’s how we actually approach it, in the order we ask the questions.
Question 1: Who will maintain this in three years?
Before any technology question, this. The right stack is the one your team can hire for, in the geography you operate in, at a price you can pay.
For Sydney businesses:
- Easy to hire: PHP/Laravel, Node.js/Express, Node.js/NestJS, .NET, Python/Django, Ruby on Rails (older but still strong here), React, Vue.
- Medium to hire: TypeScript-first stacks (Next.js, Nuxt, NestJS), Svelte, Elixir.
- Hard to hire: Rust, Haskell, Clojure, anything exotic.
If you’ll be hiring an in-house engineer or rotating freelancers, this constraint should anchor everything else. A “better” stack that you can’t staff is worse than an “okay” stack with abundant talent.
Question 2: What does the application do?
The application’s shape pushes you toward particular stacks:
Heavy form/CRUD applications
Internal tools, admin dashboards, traditional business systems. Laravel, .NET, Django, Rails are all excellent. They’ve spent 15+ years optimising for this exact shape. The “modern JS” alternatives (Next.js, Remix) work, but you’ll write more code for less benefit.
Real-time / collaborative applications
Chat, multi-user editors, dashboards with live data. Node.js + Socket.io, Elixir/Phoenix (genuinely brilliant at this), or Next.js + Pusher/Ably/Liveblocks.
Data-heavy / analytics applications
Lots of aggregation, big datasets, charts and reports. Python + FastAPI with a strong data layer (Postgres, ClickHouse, BigQuery) is often the right answer.
API-heavy / integration-heavy applications
Many third-party APIs, complex business logic. Node.js/TypeScript is hard to beat - typed integrations, huge ecosystem, fast iteration.
Mostly content with light interactivity
Marketing site + a small app area. Astro for the marketing, with a small Next.js or Remix island for the interactive parts.
Mobile-first application
React Native with Expo if you want one codebase for iOS and Android. Flutter if you have flexibility on hiring (smaller talent pool in Sydney).
Question 3: What’s the team’s existing skill?
Stack selection in a vacuum is silly. If your in-house team already runs three Laravel apps and you’re adding a fourth, build it in Laravel. The cost of learning a new stack - onboarding, hiring, code conventions, hosting - is real. A 10% better stack is rarely worth a 30% productivity hit while everyone learns it.
The exception: if the existing stack is genuinely a poor fit for the new application (a Laravel team trying to build a real-time collaborative editor), pay the learning tax. Force-fitting tools costs more in the long run.
Question 4: What’s the deployment story?
Some stacks are easier to host than others. Roughly:
Trivial to host
Static sites (Astro, Eleventy) on Vercel, Netlify, Cloudflare Pages - usually free.
Easy to host
Next.js, Remix, Nuxt on Vercel or Netlify - managed, scaling handled. ~$0–60/month for small-medium apps.
Moderate to host
Laravel, Rails, Django, Express on Cloudways, DigitalOcean App Platform, Railway, Fly.io. You manage less than bare VMs but more than serverless. ~$30–150/month for small apps.
Harder to host
Anything self-hosted, anything with significant operations needs. Kubernetes, custom infrastructure, complex deployments. ~$200+/month and a real DevOps capability.
For most SMBs, “moderate” is fine. Don’t chase the trivial-to-host stack if the application doesn’t fit it.
The stacks we actually pick most often
For internal tools and admin systems
Laravel + Inertia + Vue. Rapid development. Excellent ecosystem. Lots of Sydney talent. Inertia bridges the gap to modern SPAs without the SPA tax.
Alternative: NestJS + Next.js, especially if the team is TypeScript-first. More code, more flexibility.
For customer-facing applications with content + auth
Next.js (App Router). Strong SSR/SSG hybrid. Excellent SEO story. The ecosystem (NextAuth, tRPC, Prisma) makes feature work fast.
Alternative: Remix. Often more elegant for form-heavy apps.
For high-performance marketing sites with a small app area
Astro for the marketing, Next.js or Remix for the app area. Two deployments, one domain. Best of both.
For real-time collaborative apps
Next.js + Liveblocks (for the easy 80%). Phoenix LiveView (if you want serious performance and your team can handle Elixir).
For mobile-first
Expo + React Native. Sydney has decent React Native talent. Code shares with the web app.
The database question
Almost always PostgreSQL for the primary database. It’s the most flexible, the most powerful, the most reliable, and has the broadest hosting options.
MySQL is fine but Postgres has overtaken it for new projects.
MongoDB rarely. It’s faster to start with but slower to maintain. Most projects regret choosing it once schemas stabilise.
SQLite - surprisingly viable for many small applications, especially with Litestream or similar replication. The “scale problem” is overblown for most workloads.
Supabase / Neon / PlanetScale - managed Postgres/MySQL services. Excellent for fast-moving teams.
Specialised stores:
- Redis for caching and queues.
- Meilisearch / Algolia for search.
- ClickHouse / DuckDB for analytics workloads.
The auth question
Almost everyone gets this wrong by building it themselves. Use a service:
- Clerk - slick, fast, great for B2C and B2B SaaS.
- Auth0 - enterprise default, more expensive.
- Supabase Auth - bundled with their database, good if you’re using Supabase.
- NextAuth / Auth.js - open source, runs in your app, free.
- Lucia - lightweight, transparent, good for full control.
Building your own auth costs months and produces a worse result than any of the above. Save the time for the actual application.
Things to avoid in 2026
A short list of choices that have aged poorly:
- AngularJS (1.x) or older Angular. End of life. Don’t start new projects here.
- jQuery as the primary front-end framework. Fine for a script tag on a static site; not for an app.
- MongoDB as the default for everything. Use it deliberately or not at all.
- CoffeeScript. Decade-old syntactic sugar nobody asks for.
- Outdated PHP (5.6, 7.x). PHP 8.2+ only.
- Self-built session management. Use a library. Always.
- NoSQL for relational data. You’ll spend years recreating SQL primitives, badly.
- A microservices architecture for an MVP. Start as a monolith. Split if and when you must.
The honest performance hierarchy
If absolute application performance is the priority:
- Rust / Go - fastest. Hardest to staff.
- Elixir / Erlang - extraordinary for concurrent workloads.
- Java / Kotlin - fast, mature, broadly hireable.
- .NET / C# - fast, broadly hireable, especially in enterprise contexts.
- Node.js / TypeScript - fast for I/O-heavy work; vast ecosystem.
- Python / Ruby / PHP - slower per-request but rarely the bottleneck in a real app.
For 95% of business applications, the language is not the bottleneck. The database query is. The third-party API is. The N+1 query is. Picking Rust because “it’s fast” while writing slow queries is a category error.
A simple rule
Pick the stack the team would happily maintain at 2am, three years from now, when something breaks in production.
Everything else - performance, ecosystem, hype - is secondary.
Need help choosing? Get in touch and we’ll do a 30-minute stack consultation. We’ll tell you the truth even if we wouldn’t be the right team to build it.