
How to Pick the Right Tool
Every dependency you add is a promise to maintain it. Here are the questions we ask before a tool earns a place in the stack, and the stack we actually landed on.

A new tool always looks good in the demo. The demo is built by the people who made it, on a problem they chose, with the rough edges sanded off. Your job is to figure out what happens on day 400, when the person who introduced it has moved on and a junior engineer hits the edge the demo skipped.
So before anything joins our stack, it has to answer a few questions.
Who maintains it, and will they still be here next year?
A dependency is not free because it is open source. You pay for it every time it breaks, every time it lags a framework upgrade, every time a new hire has to learn it. The real cost shows up in maintenance, not installation.
We look at the boring signals. When was the last release. How fast do they close security issues. Is there a company behind it or a single burned-out maintainer. A library with a smaller feature set and a healthy team beats a clever one that nobody is tending.
Does it earn its complexity?
Every tool adds a concept your team now has to hold in their heads. That is a tax. A tool is worth it when the problem it solves is genuinely harder than the tool itself.
We ask what we would do without it. If the honest answer is "write thirty lines and move on," we write the thirty lines. Reaching for a dependency to avoid a small amount of code is how you end up with a node_modules folder you are afraid of.
The best tool is often the one you already have, used properly.
Can we leave?
Lock-in is fine when the trade is honest and the value is high. It is dangerous when it sneaks up on you. Before we commit, we look at the exit. If this tool disappeared or doubled its price, how much of our code would we have to rewrite.
We keep the core of a product in plain language and standard patterns, then push vendor-specific code to the edges. The database, the framework, the business logic stay portable. The replaceable bits stay replaceable.
What we actually use, and why
Here is where we landed, and the reason in one line each.
- Next.js for web. One framework for rendering, routing, and server logic, with an escape hatch when we need one. It is boring in the best way.
- TypeScript everywhere. Types are the cheapest tests you will ever write, and they catch the mistakes that wake you up at night.
- PostgreSQL with Prisma. A real relational database we will not outgrow, with a schema we can read out loud. We reach for Postgres long before anything trendier.
- Tailwind for styling. It keeps design decisions in the markup where you can see them, and it deletes cleanly.
- The Vercel AI SDK for anything model-related. It gives us one interface across providers, so swapping Claude for a fallback model is a config change, not a rewrite.
- MCP for connecting agents to tools. One protocol instead of a new bespoke integration per system.
- Resend, Twilio, UploadThing, Stripe for email, messaging, uploads, and payments. Each does one job well and gets out of the way.
None of this is exotic. That is the point. We spend our novelty budget on the product, not the plumbing.
The rule underneath all of it
Pick the tool that the smallest version of your team can still operate at 2am. Excitement is a bad reason to add a dependency, and "everyone is using it" is worse. The right tool is the one you will still be glad you chose when it is no longer new.
Have something to build?
Let's turn your vision into a shipped product, fast.



