Is React a library or a framework? This is an age-old question in web development that just keeps coming back. Like many, I don’t think coming up wiht a definitive answer to this question on my own offers any immediate value in my day-to-day work. Nor do I expect my answer to change anyone’s mind or behavior. But it can still be a fun and useful exercise in a sense that a clear picture of what a tool is can help determine how to wield it.
Plus, I always enjoy exploring language and concepts in tech discourses. After all, don’t I write on this blog for myself? So, here goes.
React the library
Another argument for React the library points to its “unopinionated”-ness. (For example, see here.) That is, React does not provide solutions for common needs in building a full-fledged UI application, such as styling, routing, global state management and data fetching. Due to this limited scope, the argument goes, React cannot be considered a framework.
React the framework
There’s a common saying in programming that goes, “your code calls a library, and a framework calls your code.” When building a React application, we write code for components and then hand it to React to execute. This inversion of control is what makes it possible for us to declaratively describe user interface, which has always been a core feature of React. React is surely a framework in that regard.
Further, using React requires adopting its mental model. Thinking in React—if you will. React is prescriptive in a sense that it comes with a coherent vision of what building UI should look like. React tells us that it should be broken into a hierarchy (or tree) of components, which ideally are pure calculations that return the static description of UI. Sure, mutations and side effects are unavoidable, but they should be kept to minimum. As users, we build on this vision. While fighting this vision is not impossible, doing so is difficult and prone to errors. That’s what frameworks do.
In addition, React is increasingly expanding its focus beyond rendering the UI view. For instance, its latest features—React Server Component and other related APIs—evidently seem motivated by and concerned with async data management. In fact, React now openly speaks of the “React architecture”:
Excited to see the release today of Next.js 13, which includes beta support for React Server Components as part of the React architecture!
Library in form, framework in substance
Until recently, I was on the React the framework camp. Calling React a library just didn’t make sense to me however limited its scope may be. React is a UI runtime and when I’m using React, React runs the show, not me. That, to my eye, was more than enough to make React a framework.
Then I realized that the whole library vs framework might have been a false choice all along! What makes a piece of software a library is, ahem, orthogonal to what makes a piece of software a framework. Library is about how software is distributed (form) while framework is about how software behaves or relates to its user (substance). As such, they simply aren’t competing, mutually exclusive alternatives.
Based on that, here’s my answer to the original question: Yes.
More specifically, React is a domain-specific language for building UI that serves as a framework and is distributed as a set of libraries.
Cool, React is both a set of libraries (in form) and a framework (in substance).2 But why throw DSL in the mix? Because, in my view, what React offers at its core is a focused set of vocabulary tailored to a particular problem domain, i.e. that of building UI. I believe calling React a DSL correctly highlights its scope and significance while gracefully sidestepping the original (false) dichotomy of library vs framework. That’s a plus!
Abstractions all the way down
What does this all mean for Next.js, Remix, and others? Are they still frameworks? Something else? Perhaps metaframeworks or “distros”?
Before answering this question, let’s first recall that a function that calls another function in its body is just a function, not some meta-function. Sure, the notion of higher-order function exists, but that’s still a type of function with certain properties. We can say the same thing about an array with another array as its element and so on.
In the same way, there is no inherent contradiction in a framework using another framework as a building block. They just sit on different levels of abstraction. After all, calling something a framework or not doesn’t make any difference in behavior. Nonetheless, denoting something a framework helps us better conceptualize how it relates to the application we build with it and vice versa.
Well then, I guess that makes Next.js and friends just frameworks. Frameworks for building web applications with React as a key building block. That said, I’m not against labels like metaframework—they are useful to an extent that they make it easier for us to communicate relevant ideas. What’s not to like?
At the moment, the beta docs site meant to replace the current site is almost complete. While the beta docs does not feature the same tagline on its landing page, it does say React is a library in a couple of places (e.g. here and here). ↩
I’m not sure we can insist that React is a single library any more. Yes, React core is a single npm package, but to really build React applications, we need other official packages such as
react-domas well as
react-refresh, Babel plugins, ESLint plugin, and more. ↩