← All posts

Choosing a stack you won't regret

Choosing a stack you won't regret

Stack choice generates more argument per hour than almost anything else in software, and most of that argument is about the parts that do not matter much. React or Vue is a preference. Tailwind or CSS modules is a preference. You can change either in a sprint and nobody outside the team will notice.

A few decisions are not like that. They are load-bearing, and undoing them means rewriting things that were working.

Sort the decision before making it

Two columns separating stack decisions that are reversible in a week from ones that are expensive to undo.

Spend your deliberation on the right column. The left column deserves a default and a quick decision — pick what the team already knows and move on, because the cost of being wrong is a week and the cost of debating is often longer.

The one framework choice that is hard to reverse

It is not which framework. It is whether pages are rendered on the server.

Comparison of client-rendered single-page applications against server-rendered frameworks.

A single-page app sends an empty shell and fills it with JavaScript. That is a good trade for a dashboard people log into — after the first load it feels instant, and nobody needs Google to find the invoice screen. It is a bad trade for anything strangers must discover, because the crawler that arrives sees the empty shell unless you have added prerendering, and prerendering is machinery you will maintain forever.

Server-rendered frameworks invert that. Next.js and Nuxt send finished HTML, which is why they dominate for anything content-led — and because the API lives in the same project, there is no second codebase to keep in step.

Moving from one model to the other later is not a refactor. It is a rewrite of every page plus the deployment around it. This is the decision to think about.

The database question, honestly

Most applications are relational. Orders belong to customers, invoices have line items, and you will want to ask questions that span three tables. Postgres, MySQL and SQL Server all do that competently, and choosing between them is mostly about what your team and your hosting already know.

Choose MongoDB when your data genuinely is documents — varied shapes, few cross-entity queries, no accounting to reconcile. Choose SQLite when the app is single-writer or embedded, which is a real category and not a toy one.

The failure mode worth naming: choosing a document store for relational data because it feels faster to start, then rebuilding joins in application code six months later. That rebuild is slower than the schema you avoided writing.

What it means when you do not have to commit early

CodeSky generates against six frontend frameworks — Angular, React, Vue, Svelte, Next.js and Nuxt — and five databases: Postgres, MySQL, SQL Server, SQLite and MongoDB. You pick at project creation, and the schema, API and interface are generated together against that choice rather than adapted to it afterwards.

The honest claim is narrow. Generation makes it cheap to start in a stack, and cheap to build a second version in a different one to compare. It does not make the load-bearing decisions reversible — a rendering model change is still a rewrite, generated or not. What it removes is the cost of finding out.

A shorter way to decide

Ask who needs to find this application. If the answer is "people who already have an account", almost any stack works and you should pick on familiarity. If strangers have to find it through a search engine, server rendering stops being a preference and becomes a requirement.

Then pick the database from the shape of your data, not the shape of the conversation you last read online, and spend the time you saved on the schema.

← All posts