A practical launchpad for new developers and vibe coders
You have a new idea. You want to make an app.
Whether you're using AI to help or getting elbows-deep in the syntax yourself, getting started can be confusing — and sometimes intimidating. There are seemingly endless technologies, frameworks, libraries, tools, acronyms, and opinions to navigate.
The good news is that it's simpler than it looks.
A lot of those technologies are solving the same fundamental problems. There may be dozens of frameworks for building a web application, hundreds of libraries for handling different tasks, and countless ways to deploy your finished project. Choosing between them often comes down to the needs of the project and the preferences of the developer.
I've taken what I've learned over the past seven years of development and distilled it into some simple concepts and tools that I wish someone had handed me when I started. Hopefully, this will save you some headaches, failed builds, irritated customers, and maybe even a few tears.
This is the setup that I use. It is not a universal standard, it is not the "best" stack, and it certainly isn't the only way to build software. Every developer develops their own workflow, and your own toolset should evolve as you discover new skills.
Think of this as a launchpad, not a rulebook.
If you only remember three things:
If you're completely new, don't try to learn this entire page.
Start with VS Code, your browser, Node.js, and TypeScript. Build something small. When you encounter a problem that requires a database, learn PostgreSQL. When you need a backend, learn NestJS. When you need a more complicated UI, learn the Angular pieces you need.
You don't need to know where the road ends before you start walking.
The Bare Essentials
Before choosing a framework, there are a few things you'll need regardless of what you're building.
VS Code
With today's LLMs and AI-first IDEs, it is possible to build an app without spending much time looking at the underlying code.
You can do that.
But if you want to become a good developer, I'd strongly recommend getting your hands dirty and learning what's happening behind the curtain.
VS Code is a great starting point because it's essentially a blank slate. It can handle almost any language and adapt to your workflow through extensions and customizations.
I have an article about some great starting extensions here: Suggested VS Code Extensions to Try
Web browser
Very hard to test a web app you're developing without one.
Your browser also contains some incredibly useful developer tools for inspecting pages, debugging JavaScript, examining network requests, and more.
Chrome, Edge, Firefox, and Safari all have developer tools. Pick whichever you prefer.
Node.js/npm
If you're following the stack below, you'll need Node.js and its package manager, npm.
Node.js allows JavaScript and TypeScript to run outside of a web browser, which makes it useful for building backend applications and development tools.
npm provides access to a huge ecosystem of packages and is also how we'll install the frameworks used in this stack.
You can build simple backend servers with Node.js on its own. As your projects grow, however, a framework can provide structure and features that make the application easier to build, maintain, and expand.
Suggested Framework Stack
The Basics
Backend: NestJS
"Nest is a framework for building efficient, scalable server-side applications."
Install the Nest CLI with:
npm install --global @nestjs/cli
- TypeScript
- Clear separation between controllers, services, and other application components
- Introduces useful concepts such as dependency injection and modular architecture
- Encourages you to organize your application instead of putting everything into one giant file
- Scales from small APIs to large applications
- Uses many of the same concepts and language as Angular
NestJS is a particularly nice starting point if you're interested in learning how larger applications are structured. You don't need to understand the entire framework before you start — learn the pieces as your application needs them.
Web frontend/client: Angular
"The web development framework for building modern apps."
Install the Angular CLI with:
npm install --global @angular/cli
- TypeScript
- Component-based UI development
- Common patterns with NestJS
- Dependency injection and services
- Built-in support for routing, forms, HTTP communication, and other common application requirements
- Provides an established structure for larger applications
Angular can feel like a lot at first. That's okay. You don't need to learn everything before building your first application. Start with components and templates, then introduce services, routing, forms, HTTP, and other concepts as you need them.
Database: PostgreSQL or SQLite
PostgreSQL is a mature, open-source relational database system and is my primary recommendation for traditional server-backed applications.
- SQL is a valuable and transferable skill
- Strong support for relational data and relationships
- Supports useful features such as JSON/JSONB and array data types
- Mature ecosystem and extensive documentation
- Suitable for everything from small applications to very large systems
SQLite is another excellent option, particularly for smaller or local applications. Unlike PostgreSQL, SQLite doesn't require a separate database server — the database is simply a file that belongs to your application.
A simple rule of thumb:
- SQLite: Simple, local, or embedded applications
- PostgreSQL: Applications with a dedicated backend/database server, multiple users, or more complex data requirements
You don't need to become a database administrator before building your first application. Start with tables, relationships, basic queries, and indexes, then learn more as you need it.
Mobile client: Flutter
"Build apps for any screen."
Flutter allows you to build applications for Android, iOS, desktop, and other platforms from a shared codebase.
Flutter uses Dart, so I'd consider it a natural next step once you're comfortable with web development rather than something you need to learn immediately.
- One codebase can target multiple platforms
- Excellent for building mobile applications
- Dart is another approachable, strongly typed programming language
- Shares many familiar concepts with TypeScript
Publishing mobile applications also introduces additional considerations such as developer accounts, platform-specific requirements, testing, and app-store processes.
Advanced Concepts
Once you've built an application, you'll eventually run into problems that aren't about writing the application itself.
That's where some of these concepts come in.
Object Storage
Applications often need to store files such as images, documents, backups, or other large objects.
One common solution is object storage, with Amazon S3 being one of the best-known examples.
There are several approaches:
- Hosted object storage: Let a provider handle the infrastructure.
- Self-hosted object storage: Run an S3-compatible service yourself.
- Local filesystem: Sometimes perfectly adequate for a small application.
The right choice depends heavily on the application and its requirements.
Deployment
Getting your application from your development machine onto the internet is a whole topic of its own.
There are roughly three levels of complexity:
Managed hosting
Services such as Netlify, Vercel, Firebase, or GitHub Pages can handle much of the infrastructure for you.
Cloud VPS
You rent a virtual server and take responsibility for considerably more of the configuration yourself.
Self-hosting
You run the application on hardware that you control.
This could be a spare computer, a home server, or another machine running Docker/Compose.
Start with the simplest option that meets your needs. You can always learn the more complicated approaches later.
Important Concepts to Consider When Designing an App
The code isn't the only thing you need to think about.
Even a small application should make you stop and ask a few questions:
- Data privacy: What personal information does the application collect? Does it actually need it?
- Compliance: Are there laws or regulations that apply to the data you're handling?
- Security: How could someone misuse the application or gain access to information they shouldn't have?
- Secrets: Never commit API keys, passwords, tokens, certificates, or other sensitive secrets to your repository.
- The user: What is the application actually like to use? Don't design entirely around what is convenient for you as the developer.
- Testing: If other people are going to depend on your application, tests aren't optional. The more important the application becomes, the more important automated testing becomes.
- Failure: What happens when the network goes down, the database is unavailable, an API changes, or a user does something unexpected?
If you're using AI to build the application
AI can dramatically reduce the amount of code you need to write yourself, but it doesn't remove the need for planning.
In fact, the opposite can be true.
When an AI agent is allowed to make decisions without clear requirements or constraints, it can introduce unnecessary functionality, make inconsistent architectural decisions, or solve a problem differently from what you intended.
Clear requirements, project structure, constraints, and verification steps give the AI something concrete to work against.
The AI can write the code. You still need to decide what the software should do.
General Programming Concepts
Not a deep dive, just a few concepts I wish I had learned sooner.
You don't need to master these concepts before you start building software. In fact, you'll probably understand them much better after you've built something that gives you a reason to care about them.
SOLID and DRY
You don't need to memorize the SOLID acronym right away. The important idea is that your code should have clear responsibilities and shouldn't become unnecessarily tangled.
DRY means Don't Repeat Yourself. If you're copying the same logic into five different places, there's probably a better way to organize it.
SOLID is a collection of principles that help you design software that is easier to understand, change, and maintain.
These concepts can seem abstract when you're starting out. That's normal. You'll start recognizing them naturally as your applications become more complicated.
Git branches
A Git branch gives you a separate line of development without immediately changing the code everyone else is using.
A simple workflow might have a dev branch where new work is integrated and a main branch representing code that is ready for release.
You can create a feature branch, make changes, test them, and then merge those changes back into dev without disrupting the rest of the project.
There are many different Git workflows, so don't treat dev and main as universal rules. The important thing to understand is why branches exist: they give you a safe place to make changes.
Git basics
At minimum, become comfortable with:
-
clone— get a repository onto your computer -
pull— get changes from the remote repository -
commit— record a set of changes -
push— send your commits to the remote repository -
branch— create a separate line of development -
merge— combine changes from one branch into another -
pull request— propose a set of changes for review and merging
You don't need to memorize every Git command. Learn what the commands are doing and use documentation when you forget the exact syntax.
Naming conventions
Good names make code easier to understand.
Compare:
x = getData()
with:
userProfile = getUserProfile()
The second version tells you what the value actually represents without requiring you to read the function to figure it out.
Different languages and frameworks have established conventions for naming things. Follow them where practical.
For example:
| Platform | Language | Convention |
|---|---|---|
| Backend functions/variables | TypeScript | camelCase |
| Backend entities/classes | TypeScript | PascalCase |
| Database tables/columns | SQL | snake_case |
| Web frontend functions/variables | TypeScript | camelCase |
| Web frontend classes/components | TypeScript | PascalCase |
| Web frontend HTML attributes | HTML | kebab-case |
| Web frontend CSS classes/properties | CSS | kebab-case |
| Mobile frontend functions/variables | Dart | camelCase |
| Mobile frontend classes/widgets | Dart | PascalCase |
File naming conventions may differ by framework. For example, Dart conventionally uses
snake_casefor file names, while Angular commonly useskebab-casefor source file names.
The exact convention is less important than understanding what you're looking at and being consistent with the conventions of the project you're working in.
Separation of concerns
This is one of those concepts that sounds much more complicated than it is.
Don't make one piece of your application responsible for everything.
For example, your code that handles an HTTP request shouldn't also be responsible for rendering the UI, talking directly to the database, sending emails, and deciding all of your business rules.
Separate those responsibilities into appropriate parts of the application.
This makes your code easier to understand and means you can change one part without accidentally breaking everything else.
You'll encounter this idea under many different names — services, controllers, components, repositories, modules, layers, and more. The terminology changes, but the underlying idea is the same.
Don't be afraid of refactoring
The first version of your code doesn't have to be the final version.
As you learn more about the problem, you'll often discover that something you wrote yesterday could be organized better today. That's normal.
Refactoring means changing the internal structure of your code without intentionally changing what the application does.
Maybe a function has become too large. Maybe two pieces of code are doing almost the same thing. Maybe you've discovered that something belongs in a service instead of a component.
Fix it.
You don't have to get everything right the first time. Good developers spend a significant amount of time improving code they've already written.
Read error messages
This sounds obvious, but it's one of the most valuable skills you can develop.
When something breaks, read the error before asking an AI to fix it.
The error message may tell you exactly what went wrong, which file it happened in, and sometimes even which line caused it.
You don't need to understand every word immediately. Start by identifying:
- What kind of error is it?
- Which file caused it?
- Which line caused it?
- What was the application trying to do?
Then investigate from there.
Learning to understand errors turns debugging from "the computer hates me" into a solvable problem.
Tests are documentation
Tests aren't just there to prove that your code works today.
A good test also tells the next developer — which might be you six months from now — what the code is supposed to do.
If you change something and a test suddenly fails, that failure can tell you that you've changed behaviour that another part of the application depends on.
You don't need 100% test coverage on your first weekend project. But if you're building something other people will depend on, start treating tests as part of the application rather than something you add after the "real" work is finished.
Learn to read code you didn't write
Eventually, you'll encounter code that you didn't write yourself.
Maybe it's an open-source library. Maybe it's a coworker's code. Maybe it's something an AI generated three months ago that you no longer remember.
Being able to read existing code is just as important as being able to write new code.
You don't need to understand an entire project before changing it. Start at the piece you're interested in and work outward:
What calls this? What does this call? What data goes in? What comes out?
You'll gradually build a mental model of how the pieces fit together.
One Last Thing
Don't get caught up in choosing the "perfect" technology, or feel like you need to understand everything before you start building.
Your first application will probably be messy. You'll make mistakes, discover better approaches, rebuild parts of it, and eventually look back at your early code and wonder what on earth you were thinking.
That's okay.
These aren't rules you need to memorize. They're ideas that become more useful as your applications grow and you gain experience.
Build things. Break things. Fix them. Then build something better.
That's how you learn to develop software.
And that's the whole point of this guide: give yourself enough of a map to start moving, then learn the rest along the way.
That's development.
Top comments (0)