So You Want to Build AI-Generated Apps And You Know Absolutely Jack about Computer Science? (vol. 4)
Two Foundational CS Concepts for Anyone
So far in this series you’ve learned how to:
talk to AI effectively and get it to respect your working prefs
gained some sense of what’s going on under the hood
ask for what you actually want more clearly
use Github to build up your app checkpoint by checkpoint rather than all at once.
Now that you are armed with the pre-requisites for AI-generated software building, what’s a good way to actually build software?
It’s a big question, one that thousands of books have been written about and thousands of PhD’s earned over. In the next few parts of this series we will touch on some of the most fundamental CS concepts that will have the most impact for you as someone who knows absolutely jack about computer science.
Separation of concerns
Imagine you let your spouse run all of their finances together with your own from your bank account. and your kids’ finances, and your 2 small businesses that you run on the side, and your grandma’s finances.
It doesn’t take too much imagination to picture what a disaster this strategy will be come tax time. In this banking scenario, you have no separation of concerns. The consequences are equally disastrous when you build software with no separation of concerns.
In software, mixing multiple concerns in the same code is generally a strategy to produce buggy, unmaintainable, un-debuggable software.
Separation of concerns is an underlying guiding principal of development whether you are writing the code or an AI is writing the code. When you are designing the overall pieces of your app and how they fit together (known as architecture) you should always be thinking in terms of separating concerns.
“what are the concerns?”
The most common concerns of software are usually, but not limited to:
database
backend
frontend
Database: just think really advanced excel sheets. The place for reference data to make the app function (like say a list of tax codes for each state), user-contributed data (username, email, phone, etc), and more.
Back end: just think business logic. The part of the app that receives user requests and does “server stuff” like updating the database before returning a response.
Front end: mostly referring to what users visually see and experience while using the app.
I don’t know what language you’re going to be vibecoding in or the nature of the app you’re building. The point here is that generally, you are going to have a lot of business logic and database operations throughout your app. Those should probably be handled in a consistent way. The front end of your app probably shouldn’t break when the business logic or database fails. To do that, you need separation of concerns.
prompt:
"without doing any implementation, based on this attached PRD1 we built, generate an outline document in markdown format for a good [“front end”, “database”, or “back end”] architecture and project structure that exercises good separation of concerns”
Save the resulting markdown docs in a /docs folder in your project, and have the AI reference these in all development steps2
Modularity
Another big picture concept that is separate but related to separation of concerns is modularity.
In an ideal world, your entire codebase resembles a big set of legos, not a plate of spaghetti.
When it’s legos, you effortlessly move bricks around, snap em in place instantly, swap em out for different bricks when you change your mind. A 4x2 brick always fits in every 4x2 hole of any lego set.
The opposite of modular code is spaghetti code: you grab the end of one noodly line of code, and as you chase the noodle into the pile of code, it’s all mixed up and intertwined together until your original line of thought all but vanishes. You can’t pull on one spaghetti thread of code without disturbing the pile on the plate.
AVOID THIS.
Examples:
you notice that for every db operation your agent implements, its generated code every time for configuring and connecting to a db, checking that the user is authenticated/logged in, and then some output formatting of the data that it receives. This would be an opportunity to make all of that functionality modular, extracted out into its own database connector piece, which handles authentication and formats the output. You would then re-use this db module everywhere you make a db request so requests always done consistently.
your app might have a popup dialog that prompts the user with yes and no action buttons. you are using this popup in at least 5 places, and you start to notice that each of the popups, though similar, have a slightly different look and feel. When you look at the AI generated code you find there are 5 different implementations of the popup. Ask the AI to refactor all implementations to use the same single modular component.
Building off of Vol 2 of this series with creating project documentation, what you want to do is generate your database documentation , front end docs, back end docs, overall project organization docs, and docs for any other relevant piece. Instruct AI to always code adhering to these documents.
When things seem to be going wrong, put the agent in “ask” mode and prompt:
prompt:
“does this exercise good separation of concerns?”
“how could we make this part more modular?”
That’s all for today, thanks for stopping by, and good luck building!
Come back for more parts of the series. It’s faster and costs less than getting a computer science degree.
If you are just joining us, catch up with the series here:
Vol 1: Day 1 Ground Floor Basics To Help You Out
Vol 2: You're building a building without a blueprint
Vol 3: Untangle failed codebases with this one weird trick
If you want me to cover a specific question or topic, comment below.
If you have found this useful to your vibecoding, you can support me by buying me a coffee:
Build PRDs with AI as shown in Vol 2 of this series
if using Cursor, you can create a cursor rules file that says “make sure all code you generate adheres to the technical documentation in @docs”



