The 90% Stack

A Web Development Kit Built for the Real World

Most projects don’t need AWS. They don’t need a dedicated DevOps team, a microservices architecture, or a six-figure cloud bill. What they need is a stack that’s fast to set up, easy to maintain, flexible enough to handle whatever the client throws at it, and reliable enough that you’re not firefighting at 2am.


An LLM (Sonnet 4.6) was used to clean up these notes and make them more readable. All content, opinions, and workflow tips are my own. Strap in — it’s about to get technical.

Frontend

Astro

The backbone of the frontend. Astro’s core idea — ship as little JavaScript as possible by default — is the right idea. But the real reason it’s in this stack is flexibility. You can choose any frontend framework you want, or none at all. In practice I primarily use Alpine.js for interactivity, which keeps things light and close to the HTML. But when a component genuinely benefits from React — and React has an enormous community and ecosystem behind it — you can drop it in without rebuilding anything. That optionality matters on client projects where requirements shift.

Astro also handles server actions and server-side rendering out of the box, with in-memory caching that covers the vast majority of performance needs without reaching for a dedicated caching layer on the frontend.

Tailwind CSS

Utility-first CSS has won, and Tailwind is why. The speed of going from design to implementation without context-switching to a stylesheet is the real benefit. It’s not for everyone, but once it clicks, going back feels like a regression. Consistent spacing, responsive design, and dark mode all become mechanical rather than effortful.

DaisyUI

Tailwind gives you primitives. DaisyUI gives you components. Buttons, modals, cards, navbars, form elements — all pre-built, all Tailwind-based, all customizable through CSS variables. The key advantage is that it works across any frontend framework. Whether a project uses Alpine, React, or plain HTML, DaisyUI components work without modification. The theming system is genuinely good — a single config change re-skins an entire project, which clients love and developers appreciate on multi-brand work.

GSAP

JavaScript animation has a lot of options. GSAP is the professional choice and has been for over a decade for good reason. It’s fast, reliable across browsers, and the API is intuitive enough that complex animations don’t require complex code. Scroll-triggered animations, SVG morphing, timeline-based sequences — GSAP handles all of it without the performance issues that plague CSS-only approaches on complex interactions.

The reason it’s in this stack is specific: motion elevates user experience in ways that are hard to justify until a client sees it. A well-timed page transition or a carefully animated data visualization does real work for perception of quality. GSAP makes that achievable on a normal project timeline.


Backend

Directus

Directus is the kind of tool that’s hard to explain until you’ve used it, then hard to imagine working without. Connect it to a PostgreSQL database and you immediately get a full REST and GraphQL API, a polished admin panel, user management, role-based permissions, file handling, and webhook support — all without writing a line of backend code.

For client projects this is transformative. A large team can use the admin panel on day one without training. Non-technical stakeholders can manage content, run reports, and update data without going through a developer. That alone removes entire categories of ongoing maintenance work.

When a project needs custom logic, Directus doesn’t get in the way. You can write your own extensions, add custom middleware, and build custom endpoints that live alongside the auto-generated API. It scales from a simple content site to a complex multi-role application without switching tools.

PostgreSQL

The database. Reliable, fast, well-documented, and supported everywhere. No strong argument needed — it’s the default choice for good reason and Directus works with it natively.

Redis

In-memory caching and session storage. Directus supports Redis out of the box for caching query results, which makes a meaningful performance difference on data-heavy projects. Simple to set up, small footprint, and it handles queue-based tasks if the project grows in that direction.


Infrastructure

Cloudflare

Cloudflare sits in front of everything and handles a lot. CDN and global caching, image optimization, DDoS protection, SSL, object storage for assets and backups — all under one dashboard, all at a price that’s genuinely competitive. The reliability has been exceptional. It’s the kind of infrastructure layer you set up once and stop thinking about, which is exactly what it should be.

Object storage on Cloudflare R2 in particular is worth highlighting. No egress fees, S3-compatible API, and it integrates cleanly as a backup destination and static asset host. For most projects it replaces the need for a separate storage provider entirely.

Single Server + Coolify

Here’s where the philosophy of this stack becomes explicit.

The big cloud providers — AWS, Google Cloud, Azure — are genuinely impressive pieces of infrastructure. They’re also optimized for teams, not individuals or small agencies. Serverless functions, managed Kubernetes, auto-scaling workers — these are solutions to problems that most projects never actually have. Getting them right requires dedicated engineering time, and the billing complexity alone can consume hours of work.

A single well-specced server handles the vast majority of real-world traffic loads. Paired with Cloudflare’s caching in front of it, the effective capacity is much higher than the raw server numbers suggest. Periodic backups to Cloudflare R2 mean you’re not one hardware failure away from losing everything. And when a project genuinely outgrows a single server — when you have the traffic numbers and the team to prove it — migrating to larger infrastructure is straightforward. The same stack runs anywhere.

Coolify is the management layer that makes this practical. It’s an open-source self-hosted platform that handles deployments, environment variables, SSL, reverse proxy configuration, database management, and monitoring through a clean UI. No command-line required for day-to-day operations. It removes the friction that makes self-hosting feel risky, and it’s a project I believe in enough to have contributed to both in code and financially.

Simple is not a compromise. Choosing simplicity intentionally, knowing what you’re trading and what you’re gaining, is good engineering. The best stack is the one your team can ship confidently on and maintain without heroics — and for 90% of projects, this is that stack.


The Full Picture

LayerToolWhy
FrameworkAstroFramework-agnostic, SSR, server actions
InteractivityAlpine.js + React (optional)Lightweight default, rich ecosystem when needed
StylingTailwind CSSSpeed and consistency
ComponentsDaisyUICross-framework, customizable, production-ready
AnimationGSAPProfessional motion, reliable performance
CMS / BaaSDirectusAdmin panel, API, extensions, all-in-one
DatabasePostgreSQLReliable, well-supported
CacheRedisQuery caching, sessions
CDN / StorageCloudflareFast, reliable, budget-friendly
HostingSingle server via CoolifySimple, maintainable, scalable when ready

When This Stack Isn’t Enough

To be clear about the 10%: if you’re building something that needs true horizontal auto-scaling, multi-region failover, or compliance infrastructure — healthcare data, financial systems, enterprise SLAs — this stack isn’t the answer. Those projects need dedicated infrastructure teams and the budget that comes with them.

But most projects aren’t those projects. Most projects need to ship, work reliably, be maintainable by a small team, and not require a platform engineer to keep the lights on. Build for the reality of the project in front of you, not for the theoretical scale you might someday reach. You can always grow into complexity. Growing out of it is much harder.

Let's Move it, Move it. Let's Move it, Move it. Let's Move it, Move it. Let's Move it, Move it.
Let's Move it, Move it. Let's Move it, Move it. Let's Move it, Move it. Let's Move it, Move it.