Is React a Framework or Library? Understanding the Architectural Distinction
React is a library because it provides a focused API for building user interfaces without prescribing application architecture, while Angular is a framework that controls the entire application flow through inversion of control.
When developers ask whether React is a framework or library, they are examining the scope of control and architectural decisions. According to the facebook/react source code, React deliberately limits its surface area to component rendering and state management in files like packages/react/src/React.js, leaving routing, data fetching, and build configuration to external packages. This design philosophy fundamentally distinguishes it from full-stack frameworks like Angular.
Why React Is a Library, Not a Framework
Single-Responsibility Design
React's core mission is constrained to a single concern: efficiently rendering UI components and updating the DOM when state changes. In packages/react/src/React.js, the library exports only essential primitives such as Component, createElement, and hooks like useState and useEffect.
This scope-limited API intentionally excludes opinions on:
- Routing (handled by React Router or TanStack Router)
- Form management (React Hook Form, Formik)
- Global state (Redux, Zustand, Jotai)
- HTTP clients (Axios, Fetch, TanStack Query)
- Build tooling (Vite, Webpack, Parcel)
The Bring-Your-Own-Architecture Approach
Unlike frameworks that enforce directory structures and design patterns, React operates as a composable toolkit. You import React where needed and wire it together with any libraries you prefer. This "inversion of control" remains with the developer—you call React's functions, rather than React calling your code according to its own lifecycle.
The reconciliation algorithm in packages/react-reconciler/src/Reconciler.js demonstrates this focus: it handles the complex work of diffing component trees and scheduling updates, but makes no assumptions about how your application fetches data or manages navigation.
How Angular Differs as a Full Framework
Batteries-Included Architecture
Angular provides an end-to-end solution that dictates complete application architecture. It ships with:
- A built-in router (
@angular/router) - Forms module (
@angular/forms) - HTTP client (
@angular/common/http) - Dependency injection system
- Angular CLI for scaffolding and build configuration
This opinionated approach means Angular makes architectural decisions for you, enforcing specific patterns for component interaction, service creation, and module organization.
Inversion of Control
The defining characteristic of a framework is inversion of control. Instead of you calling into the framework, the Angular runtime boots the application and calls your components, directives, and services according to its own lifecycle. This "Hollywood Principle" (don't call us, we'll call you) fundamentally distinguishes frameworks from libraries.
Evidence from the React Source Code
The facebook/react repository structure confirms its library nature through minimal, focused exports:
packages/react/src/React.jsexports core UI primitives (Component,createElement, hooks) but contains no routing logic or HTTP clientspackages/react-dom/src/client.tsxprovides DOM-specific rendering entry points (createRoot,hydrateRoot) without dictating build configurationpackages/react-reconciler/src/Reconciler.jsimplements the internal diffing algorithm but remains agnostic about data fetching patternspackages/react/src/ReactHooks.jscontains hook implementations (useState,useEffect) focused solely on component state management
These files exemplify why React stays narrowly focused on UI rendering while allowing developers to compose any additional functionality they need. The README.md in packages/react-devtools further illustrates the ecosystem approach: developer tools complement React without being part of the core library.
Practical Examples: Library vs. Framework in Action
Minimal React Usage (Library Pattern)
The following example demonstrates React's library nature—you explicitly import and invoke React functions:
import React, { useState } from 'react';
import ReactDOM from 'react-dom/client';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
Clicked {count} times
</button>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<Counter />);
Source: packages/react/src/React.js exports the hooks; packages/react-dom/src/client.tsx provides createRoot.
Composing with Third-Party Libraries
React's library status allows you to add routing without changing React itself:
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './Home';
import About from './About';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
This demonstrates the "bring your own architecture" approach—React handles the UI, while React Router (a separate library) handles navigation.
Contrast: Angular's Framework Approach
For comparison, Angular requires you to work within its module system and dependency injection:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { HomeComponent } from './home.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent },
];
@NgModule({
declarations: [AppComponent, HomeComponent, AboutComponent],
imports: [BrowserModule, RouterModule.forRoot(routes)],
bootstrap: [AppComponent],
})
export class AppModule {}
Here, Angular controls the bootstrap process, routing configuration, and module compilation—characteristics of a framework rather than a library.
Summary
- React is a library because it provides a focused API for UI rendering without dictating application architecture, routing, or state management patterns.
- Scope limitation is evident in the source code:
packages/react/src/React.jsexports only component primitives and hooks, leaving HTTP clients, routers, and build tools to external packages. - Developer control defines the library pattern—you call React's functions (
useState,createRoot) and compose them with third-party tools like React Router or Redux. - Angular represents the framework pattern, providing batteries-included architecture with inversion of control—the runtime calls your code according to its lifecycle.
- Composability vs. completeness is the fundamental distinction: React gives you the view layer and lets you pick the rest, while frameworks provide the full stack.
Frequently Asked Questions
Can React be used as a framework?
While React is architecturally a library, you can create a framework-like experience by combining it with specific tools. Next.js, Remix, and Gatsby add routing, data fetching, and build-time optimizations to React, effectively creating opinionated frameworks built on top of the React library. However, React itself remains unopinionated about these concerns according to the facebook/react source code.
Why does the distinction between library and framework matter?
The distinction affects architectural decisions and team workflows. Libraries offer flexibility—you choose your router, state management, and folder structure, but you must integrate these pieces yourself. Frameworks provide consistency—every Angular project follows similar patterns, making onboarding easier, but they limit architectural freedom. Understanding whether React is a framework or library helps teams choose between maximum flexibility versus rapid standardization.
Is React evolving into a framework with Next.js?
No—React remains a library, while Next.js is a separate framework that depends on React. The React team maintains the core library focused on component rendering and the reconciliation algorithm in packages/react-reconciler/src/Reconciler.js. Next.js, maintained by Vercel, provides the framework layer—routing, server-side rendering, and API routes—while consuming React as a dependency. This separation of concerns keeps React lightweight and composable.
How does React's library approach affect application architecture?
React's library nature requires developers to make explicit architectural choices. You must select routing libraries (React Router, TanStack Router), state management (Redux, Zustand, Context API), and data fetching (TanStack Query, SWR). This composability, evident in how packages/react/src/React.js exports only UI primitives, allows teams to tailor stacks to specific needs but requires more upfront architectural planning than framework-based development where these decisions are pre-made.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →