{"course":{"slug":"building-apps-with-ai","title":"Building Apps with AI","url":"https://addaly.com/learn/building-apps-with-ai","level":"beginner","track":"build"},"lesson":{"slug":"choosing-a-stack-and-stopping","title":"Choosing a stack, and then stopping","url":"https://addaly.com/learn/building-apps-with-ai/choosing-a-stack-and-stopping","position":7,"of":87,"minutes":8,"answer":"Pick a mainstream stack because models write it better, write the choice down where your tool reads it, and only reconsider when you hit a specific thing you cannot do.","keyIdea":"Pick a mainstream stack because models write it better, write the choice down where your tool reads it, and only reconsider when you hit a specific thing you cannot do."},"body":{"format":"markdown","text":"## The choice matters less than the stopping\n\nThere is a week available to lose here, comparing frameworks. Do not spend it. For everything in this course, any mainstream choice works, and the cost of switching later is an afternoon, not a rebuild.\n\nWhat does matter is choosing **once** and writing it down, because a model that is not told will pick fresh every session, and by Thursday your project contains three different ways of talking to the database.\n\n## Popularity is a technical criterion now\n\nThis is new, and it is worth being explicit about. A model writes better code in a popular framework, because it saw more of it. React, Next.js, Django, Rails, Laravel, Express and Flask all have enormous public corpora. A young or niche framework produces more invented functions and more confident nonsense, because there was less to learn from.\n\nSo the boring choice is the better choice while you are relying on generated code. This will feel unfashionable and it is correct.\n\n## Four routes that work\n\n**Plain HTML, CSS and a little JavaScript.** No build step, no dependencies, one file you can open in a browser. Genuinely the right answer for a landing page, a calculator, a form that emails you. People skip this and reach for a framework, then spend two days on tooling for something that was four files.\n\n**Next.js with TypeScript.** React for the interface, server code in the same project, deploys to Vercel, Netlify or Cloudflare in one step. This is the default that most AI tools assume, which means the most reliable generation. It is also the most likely to produce a folder of concepts you do not yet understand.\n\n**Python with Flask or Django.** If you already know a little Python, or the app is mostly about data, this is the shorter road. Django gives you an admin interface and a database layer without you writing them, which for an internal tool is most of the app.\n\n**A platform.** Replit, Lovable, Bolt. The stack is chosen for you. Fastest to a working thing, and the exit cost is real: check on day one whether you can export the code and connect it to your own git repository.\n\n## The parts nobody tells you to decide\n\nA stack is more than the framework, and the unstated parts are where inconsistency creeps in:\n\n- **Database.** Postgres unless you have a reason. SQLite for something small and single-machine, and it is a real database, not a toy.\n- **How you talk to it.** An ORM such as Prisma or Drizzle, or plain SQL. Pick one. Mixing them is how you end up with two definitions of the same table.\n- **Styling.** Tailwind, or plain CSS. Both fine. Two styling systems in one project is a mess that grows.\n- **Authentication.** Never your own. A later lesson explains why in detail.\n- **Where things live.** \"Every database query goes in `lib/queries.ts`\" is worth more than any framework choice on this list, because it makes the codebase searchable by a human.\n\n## TypeScript, briefly\n\nTypeScript is JavaScript with the types written down. It costs you a little extra syntax and it catches a specific, common class of AI mistake: the model passes a value of the wrong shape between two functions it wrote at different times, and the editor underlines it in red before you ever run the code.\n\nFor generated code that nobody has read closely, that is a real safety net. Take it.\n\n## Write it down where the tool reads it\n\n```\nNext.js (app router), TypeScript, Postgres via Drizzle, Tailwind.\nAll database queries live in lib/queries.ts.\nNo new dependencies without asking me first.\nDo not add a state management library.\n```\n\nFive lines. Put them in the rules file covered in the next lesson but one, and the model stops improvising.\n\nThat third line prevents the most common form of quiet bloat: an agent that pulls in a package to solve a problem three lines of code would have solved, and now your project has a dependency you did not choose, cannot evaluate and will be asked to update in six months.\n\n## When to actually reconsider\n\nSwitch stacks when there is a specific, named thing you cannot do, not when something feels slow or you read an article. \"We need real-time updates and this is awkward here\" is a reason. \"Everyone is using the other one\" is how a working project turns into an unfinished rewrite."},"check":{"question":"Why does choosing a widely-used framework produce better AI-generated code than a newer one with a cleaner design?","options":[{"text":"Popular frameworks have simpler APIs, so there is less for a model to get wrong.","correct":false,"tempting":"Assumes popularity implies simplicity; several of the most widely-used frameworks are also the most intricate."},{"text":"The model saw far more examples of it during training, so it invents fewer functions that do not exist.","correct":true},{"text":"Popular frameworks are updated more often, so the model's knowledge stays current.","correct":false,"tempting":"Reverses the effect; frequent updates make a model's training snapshot go stale faster, which is a cost rather than a benefit."},{"text":"AI tools ship dedicated integrations for the major frameworks.","correct":false,"tempting":"Points at tooling that mostly does not exist per-framework; the advantage comes from the corpus, not from special support."}]},"prev":{"slug":"the-terminal-without-fear","title":"The terminal, for people who have been avoiding it","url":"https://addaly.com/learn/building-apps-with-ai/the-terminal-without-fear"},"next":{"slug":"the-rules-file-your-tool-reads","title":"The rules file, and what belongs in it","url":"https://addaly.com/learn/building-apps-with-ai/the-rules-file-your-tool-reads"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Choosing a stack, and then stopping', in Building Apps with AI. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/building-apps-with-ai/choosing-a-stack-and-stopping (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Choosing a stack, and then stopping","courseTitle":"Building Apps with AI","module":{"index":1,"slug":"the-machine-and-the-model","title":"The machine, and what the model can see of it"},"answer":null,"keyIdea":"Pick a mainstream stack because models write it better, write the choice down where your tool reads it, and only reconsider when you hit a specific thing you cannot do.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"the-choice-matters-less-than-the-stopping","runs":[{"text":"The choice matters less than the stopping"}]},{"t":"p","runs":[{"text":"There is a week available to lose here, comparing frameworks. Do not spend it. For everything in this course, any mainstream choice works, and the cost of switching later is an afternoon, not a rebuild."}]},{"t":"p","runs":[{"text":"What does matter is choosing "},{"text":"once","b":true},{"text":" and writing it down, because a model that is not told will pick fresh every session, and by Thursday your project contains three different ways of talking to the database."}]},{"t":"h2","id":"popularity-is-a-technical-criterion-now","runs":[{"text":"Popularity is a technical criterion now"}]},{"t":"p","runs":[{"text":"This is new, and it is worth being explicit about. A model writes better code in a popular framework, because it saw more of it. React, Next.js, Django, Rails, Laravel, Express and Flask all have enormous public corpora. A young or niche framework produces more invented functions and more confident nonsense, because there was less to learn from."}]},{"t":"p","runs":[{"text":"So the boring choice is the better choice while you are relying on generated code. This will feel unfashionable and it is correct."}]},{"t":"h2","id":"four-routes-that-work","runs":[{"text":"Four routes that work"}]},{"t":"p","runs":[{"text":"Plain HTML, CSS and a little JavaScript.","b":true},{"text":" No build step, no dependencies, one file you can open in a browser. Genuinely the right answer for a landing page, a calculator, a form that emails you. People skip this and reach for a framework, then spend two days on tooling for something that was four files."}]},{"t":"p","runs":[{"text":"Next.js with TypeScript.","b":true},{"text":" React for the interface, server code in the same project, deploys to Vercel, Netlify or Cloudflare in one step. This is the default that most AI tools assume, which means the most reliable generation. It is also the most likely to produce a folder of concepts you do not yet understand."}]},{"t":"p","runs":[{"text":"Python with Flask or Django.","b":true},{"text":" If you already know a little Python, or the app is mostly about data, this is the shorter road. Django gives you an admin interface and a database layer without you writing them, which for an internal tool is most of the app."}]},{"t":"p","runs":[{"text":"A platform.","b":true},{"text":" Replit, Lovable, Bolt. The stack is chosen for you. Fastest to a working thing, and the exit cost is real: check on day one whether you can export the code and connect it to your own git repository."}]},{"t":"h2","id":"the-parts-nobody-tells-you-to-decide","runs":[{"text":"The parts nobody tells you to decide"}]},{"t":"p","runs":[{"text":"A stack is more than the framework, and the unstated parts are where inconsistency creeps in:"}]},{"t":"ul","items":[[{"text":"Database.","b":true},{"text":" Postgres unless you have a reason. SQLite for something small and single-machine, and it is a real database, not a toy."}],[{"text":"How you talk to it.","b":true},{"text":" An ORM such as Prisma or Drizzle, or plain SQL. Pick one. Mixing them is how you end up with two definitions of the same table."}],[{"text":"Styling.","b":true},{"text":" Tailwind, or plain CSS. Both fine. Two styling systems in one project is a mess that grows."}],[{"text":"Authentication.","b":true},{"text":" Never your own. A later lesson explains why in detail."}],[{"text":"Where things live.","b":true},{"text":" “Every database query goes in "},{"text":"lib/queries.ts","code":true},{"text":"” is worth more than any framework choice on this list, because it makes the codebase searchable by a human."}]]},{"t":"h2","id":"typescript-briefly","runs":[{"text":"TypeScript, briefly"}]},{"t":"p","runs":[{"text":"TypeScript is JavaScript with the types written down. It costs you a little extra syntax and it catches a specific, common class of AI mistake: the model passes a value of the wrong shape between two functions it wrote at different times, and the editor underlines it in red before you ever run the code."}]},{"t":"p","runs":[{"text":"For generated code that nobody has read closely, that is a real safety net. Take it."}]},{"t":"h2","id":"write-it-down-where-the-tool-reads-it","runs":[{"text":"Write it down where the tool reads it"}]},{"t":"code","lang":"","label":"Text","text":"Next.js (app router), TypeScript, Postgres via Drizzle, Tailwind.\nAll database queries live in lib/queries.ts.\nNo new dependencies without asking me first.\nDo not add a state management library."},{"t":"p","runs":[{"text":"Five lines. Put them in the rules file covered in the next lesson but one, and the model stops improvising."}]},{"t":"p","runs":[{"text":"That third line prevents the most common form of quiet bloat: an agent that pulls in a package to solve a problem three lines of code would have solved, and now your project has a dependency you did not choose, cannot evaluate and will be asked to update in six months."}]},{"t":"h2","id":"when-to-actually-reconsider","runs":[{"text":"When to actually reconsider"}]},{"t":"p","runs":[{"text":"Switch stacks when there is a specific, named thing you cannot do, not when something feels slow or you read an article. “We need real-time updates and this is awkward here” is a reason. “Everyone is using the other one” is how a working project turns into an unfinished rewrite."}]}],"check":{"question":[{"text":"Why does choosing a widely-used framework produce better AI-generated code than a newer one with a cleaner design?"}],"options":[{"text":[{"text":"Popular frameworks have simpler APIs, so there is less for a model to get wrong."}],"correct":false,"tempting":[{"text":"Assumes popularity implies simplicity; several of the most widely-used frameworks are also the most intricate."}]},{"text":[{"text":"The model saw far more examples of it during training, so it invents fewer functions that do not exist."}],"correct":true,"tempting":null},{"text":[{"text":"Popular frameworks are updated more often, so the model’s knowledge stays current."}],"correct":false,"tempting":[{"text":"Reverses the effect; frequent updates make a model’s training snapshot go stale faster, which is a cost rather than a benefit."}]},{"text":[{"text":"AI tools ship dedicated integrations for the major frameworks."}],"correct":false,"tempting":[{"text":"Points at tooling that mostly does not exist per-framework; the advantage comes from the corpus, not from special support."}]}],"order":[2,3,0,1],"why":null},"prev":{"slug":"the-terminal-without-fear","title":"The terminal, for people who have been avoiding it","minutes":8},"next":{"slug":"the-rules-file-your-tool-reads","title":"The rules file, and what belongs in it","minutes":8}}}