Skip to content

What is a framework?

docs.scrimba.com

Say you are building a small web app: accounts, a feed, a settings page. Before any of your own ideas appear on screen, you need code that turns URLs into pages, code that talks to a database, code that keeps passwords safe, and code that redraws the screen when something changes. None of that is your app's idea. Every app needs it, and most of it is the same from project to project.

You could write all of that plumbing yourself, and people did, for years. It is slow, it is where the subtle bugs live, and every team ended up with a slightly different, slightly broken version of the same machinery. A framework is the accumulated answer: the shared plumbing, written once and hardened by thousands of projects, packaged with a structure that tells you where your own code goes. You build the parts that make your project yours; the framework handles the parts every project repeats.

Frameworks are not a web thing. They exist everywhere programs get built, and this chapter is about the idea itself, in any language and any field.

What a framework is (and what a library is)

The word gets used loosely, so here is the distinction that actually matters, in code:

js
// A library: your code is in charge, and calls the library when useful.
const label = dateLibrary.format(order.createdAt, "MMM D");

// A framework: the framework is in charge, and calls the code you plug in.
export default function OrdersPage() {
  return listOfOrders();
}

The first line is you steering: your program runs, and it borrows a tool for one job. The second is different in kind. You never call OrdersPage yourself. You write it, put it where the framework expects, and the framework calls it at the right moment, here, when a visitor opens the orders page.

That flip has a name: inversion of control. With a library, your code controls the program's flow and borrows helpers. With a framework, the framework controls the flow, and your code fills in the blanks it leaves for you. A useful shorthand: you call a library; a framework calls you.

The same shape appears in every corner of programming. Django receives the web request and calls your view function. Flutter runs the app and asks your widgets what to draw. Unity runs the game loop and calls your scripts every frame. pytest finds your test functions and runs them for you. Different fields, one idea: the framework owns the engine, and you supply the parts it was built to hold.

If a picture helps: a library is a toolbox sitting beside you while you build, and you reach in whenever a tool is useful. A framework is closer to a building's frame, already standing when you arrive. The walls, wiring, and plumbing have their places, and your work goes into the rooms that make the building yours. Both save you effort; the difference is who decides the shape of the build.

The structure comes with expectations, and that is a feature. Most frameworks practice convention over configuration: put files where the framework expects, name things the way it expects, and everything wires itself together with no setup code. Rails made the phrase famous, and most modern frameworks follow some version of it. The payoff is that any developer who knows the framework can open any project built on it and know where to look. The price is that the conventions are one more thing to learn before anything works, and fighting them is nearly always more painful than following them.

Inversion of control changes how you read and debug a program. In a plain script, the call stack starts in your code and everything on it is yours. Inside a framework, the stack starts deep in framework internals, and your functions appear as entries the framework chose to call: hooks, handlers, lifecycle methods. The old joke describes it exactly: "don't call us, we'll call you." Practically, that means learning a framework is less about its API surface and more about its timing, which of your functions it calls, when, and what it expects back. When behaviour surprises you, the answer usually lives in that timing, and the framework's lifecycle documentation is the map worth keeping open.

JunoFrameworks and libraries A library is a toolbox: your program runs the show and grabs a tool when it needs one. A framework is more like a building's frame: the structure is already up, and you build your rooms into it. The shorthand that made it click for me is that you call a library, but a framework calls you.
JunoFrameworks and libraries You call a library; a framework calls you, and that flip is called inversion of control. Frameworks pair it with conventions: put code where the framework expects and it wires itself up. Follow the conventions rather than fighting them, that is most of the skill of using one well.
JunoFrameworks and libraries Inversion of control means the call stack starts in the framework and your code shows up as hooks it invokes. So the real thing to learn is timing: which of your functions get called, when, and what the framework expects back. Debugging a framework app is reading its lifecycle, and the sooner that stops feeling like magic, the better.

What a framework buys you, and what it costs

The case for a framework is concrete. Problems that would take you weeks arrive already solved, and solved by people who hit the hard edge cases first: password handling, form validation, routing, rendering. Your project gets a structure that a new teammate can recognise in minutes, because it is the same structure as every other project on that framework. And you inherit an ecosystem: plugins, tutorials, answered questions, and a hiring pool of people who already know their way around.

The costs are equally concrete, and they deserve the same straight look. A framework is a large dependency you do not control, with its own bugs, its own pace, and its own opinions. There is a learning curve before your first page renders, and some of what you learn is knowledge about the framework rather than about programming. Your code bends to its shapes, which makes leaving harder the longer you stay. And frameworks move: major versions arrive, patterns get rethought, and keeping up is ongoing work you did not have as plain code.

Neither list wins on its own. The balance depends entirely on the project, so the question to ask of any framework is "does this one make this project simpler". A framework earns its place by making your project simpler. When it does, use it gladly. When it does not, the next two chapters are about recognising that early.

The ecosystem effect is the underrated entry on the plus side. On a mature framework, the odds that your problem is new are close to zero: authentication, file uploads, sending email, deploying, someone has packaged or documented each one. That converts many days of building into hours of assembling. The mirrored entry on the minus side is that this fluency is denominated in the framework: some of what you know is "how Django does it" rather than "how web servers work". Keep an eye on the general idea underneath each convenience, which is what these docs are for.

Two costs only show up in production. First, abstractions leak: the framework's convenient surface hides real machinery, and on the day the magic misbehaves, you end up debugging the machinery anyway, now through an extra layer you did not write. Budget for understanding what your framework does underneath, because eventually you will need it. Second, the upgrade treadmill is a real line item: major-version migrations of a large codebase can absorb weeks, and skipping them quietly turns into unpatched security issues instead. Weigh both against the plain-code alternative, which has fewer moving parts and nothing to migrate, but re-opens every solved problem for you to solve again, at your own risk. That trade is the subject of Choosing and learning a framework.

JunoWhat frameworks buy and cost A framework hands you solved problems, a recognisable structure, and a whole ecosystem of help. In exchange you take on a big dependency, a learning curve, and its way of doing things. Both sides are real, so the question to carry is whether it makes your particular project simpler. Sometimes the answer is a happy yes, and sometimes plain code is the calmer path!
JunoWhat frameworks buy and cost The ecosystem is the underrated half of the trade: on a mature framework almost no problem you hit is new. Keep noticing the general idea under each convenience though, or your knowledge becomes "how this framework does it" instead of how the thing works. The framework should make the project simpler; that is the whole test.
JunoWhat frameworks buy and cost Two costs bill you later: abstractions leak, so one day you debug the framework's machinery through a layer you did not write, and major-version migrations are real work that cannot be skipped forever. Price those in up front, next to plain code's own price of re-solving problems the framework had finished. I have paid both invoices; neither is fun, and neither is a reason for dogma.

Where this goes next

With the idea in place, the natural next question is what is actually out there: The kinds of frameworks tours the major families, from web to games to testing, with the most popular options in each. After that, Choosing and learning a framework gets practical about picking one, learning one, and knowing when you need none at all. And if the JavaScript examples above felt unfamiliar, the JavaScript track covers the language itself, which is the right first step before any framework built on it.