Next.js vs Plain React
A direct, feature-by-feature comparison between a plain React (Vite) setup and a Next.js project.
React Is a Library, Next.js Is a Framework
This distinction matters. A library (React) gives you tools you call when you need them. A framework (Next.js) gives you a structure you build within — it calls your code at the right time (rendering a page, handling a request) according to conventions like file names and folder structure.
Side-by-Side Comparison
| Aspect | Plain React (Vite) | Next.js |
|---|---|---|
| Routing | Install and configure React Router yourself | Automatic — folders under app/ become routes |
| Rendering | Client-side rendering only, by default | Server, static, or client — per route |
| Initial HTML | Mostly empty `<div id="root">` | Can be fully rendered HTML with content |
| Data fetching | useEffect + fetch, runs after mount | Can fetch on the server before the page renders |
| Backend endpoints | Needs a separate server (Express, etc.) | Route Handlers live in the same project |
| Image handling | Manual — you optimize images yourself | next/image handles resizing and lazy loading |
| Best for | SPAs, embedded widgets, tools behind a login | Content sites, e-commerce, dashboards, full products |
Code Comparison
Here is the same "list of posts" page in both approaches.
Plain React (Vite)
function PostsPage() { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true);
useEffect(() => { fetch('/api/posts') .then(res => res.json()) .then(data => { setPosts(data); setLoading(false); }); }, []);
if (loading) return <p>Loading...</p>; return ( <ul> {posts.map(p => <li key={p.id}>{p.title}</li>)} </ul> );}▲ Next.js (App Router)
// app/posts/page.tsx — a Server Componentasync function PostsPage() { const res = await fetch('https://api.example.com/posts'); const posts = await res.json();
return ( <ul> {posts.map(p => <li key={p.id}>{p.title}</li>)} </ul> );}
export default PostsPage;Choosing Between Them
- Choose plain React when you're building an embedded widget, a purely client-side tool, or you need full manual control over your build setup.
- Choose Next.js when SEO matters, when you want server rendering without building it yourself, or when the project will grow into a full product with multiple pages and an API.
FAQs
Not by installing a package — Next.js expects its own project structure, so adopting it usually means starting a new Next.js project and migrating components into it.
No — Next.js has its own file-based router built in, so you don't install or configure React Router separately.
Summary
Plain React and Next.js solve different layers of the problem — React renders components, Next.js turns those components into a full application. Next, you'll check the prerequisites and get your environment ready to build.