Here's a thought experiment. You want to build a blog with a few pages, a listing, some tools. How do you start?

If your answer involves npx create-next-app or composer require laravel/laravel, I have follow-up questions. Like: do you know what problem you're solving? And: is it actually the one you have?

The default has shifted

Somewhere in the last decade, the starting point for web development stopped being "write some HTML" and became "pick a framework." This happened gradually enough that nobody objected, and now it's just how things work. Junior developers learn React before they learn how the DOM works. Backend developers spin up Laravel before they've written a raw SQL query.

I don't think frameworks are bad. They solve real problems. Large teams need conventions. Complex state management needs structure. Authentication, authorization, CSRF protection — a good framework handles these correctly so you don't have to reinvent them.

But most projects aren't large-team projects with complex state. Most projects are a handful of pages, some database queries, and a bit of interactivity. And for those, a framework isn't solving a problem. It's adding one.

What you're actually getting

When you install a framework, you're importing someone else's opinions about how your code should be organized, what your directory structure should look like, how your database should be queried, and what your URL structure should be. These opinions might be good. They might be excellent. But they're still someone else's.

This matters because understanding is not optional. When your framework's router does something unexpected, you need to understand routing. When your ORM generates a slow query, you need to understand SQL. When your component doesn't re-render, you need to understand the virtual DOM. The framework didn't remove the need to understand these things. It just delayed it until the worst possible moment.

The cost nobody talks about

Dependencies rot. Every framework you install comes with transitive dependencies that will, eventually, have security patches, breaking changes, and deprecations. Your project becomes a maintenance treadmill not because of your code, but because of code you didn't write and don't fully understand.

This site runs on about 300 lines of PHP. There's a router, a markdown parser, some utility functions. No framework, no package manager, no vendor/ directory. The attack surface is small because the code is small. The maintenance burden is low because there's nothing to update except my own code. When something breaks, I know exactly where to look because I wrote all of it.

Could a framework have saved me time? Maybe. The markdown parser took a while. The list nesting was genuinely annoying. But now I understand exactly how my content gets from a .md file to HTML. When I needed to add a feature — search, for instance — I added a function. Not a package. Not a plugin. A function.

When you actually do need one

There are legitimate reasons to use a framework:

  • Team coordination. Five developers need consistent patterns.
  • Complex state management. If your UI has deeply interdependent state, a framework's model helps.
  • Authentication and security. Rolling your own auth is a well-documented path to getting breached. Use a framework or a dedicated library.
  • You've built the simple version and outgrown it. This is the right time to reach for more structure.

The key distinction: you should adopt a framework because you have a specific problem it solves, not because starting without one feels irresponsible.

The learning argument

This is the part that matters most to me. When you build without a framework, you learn how things actually work. You learn what Content-Type headers do because you have to set them. You learn how routing works because you have to parse a URL. You learn what SQL injection is because you have to prevent it yourself.

These aren't abstract concepts when you've built them from scratch. They're things you've touched, broken, and fixed. And that understanding carries forward into everything you build afterward — including projects that do use frameworks.

The best developers I've encountered aren't the ones who know the most frameworks. They're the ones who understand what the frameworks are doing underneath. You get that understanding by building without them, at least once.

The actual recommendation

Start simple. Write the code. Hit the wall where you genuinely need more structure. Then reach for the tool that solves that specific problem.

You'll know when you need a framework because you'll feel the pain of not having one. Until then, the pain you feel is just the normal discomfort of understanding what your code does.

That discomfort is called learning. Don't optimize it away.