In short
Server Components run only on the server. They can talk to your database directly, and their code never reaches the user's phone, so pages get lighter.
React components that render exclusively on the server, never shipping their JavaScript to the browser — Next.js's App Router default, reducing client bundle size.

Think of it like this
The restaurant kitchen
You never see the gas stove, the spice jars or the fridge. You only get the finished thali. Server Components are the kitchen: they do the heavy work out of sight and send only the result, which is HTML.
Watch it happen
Data stays in the kitchen
GET /courses
1/4The browser asks for the courses page.
The big ideas
What you need to know
Default in app/
Every component in the App Router is a Server Component unless you add "use client".
async and await, directly
Make the component async and await your data. No useEffect, no loading flag.
Secrets stay safe
API keys and database queries in a Server Component never get sent to the browser.
No hooks or events
No useState, useEffect or onClick here. For those, use a Client Component.
See it in code
Walk through the code
1// app/courses/page.tsx (Server Component, the default)2import { db } from "@/lib/db";3 4export default async function CoursesPage() {5 const courses = await db.course.findMany({ orderBy: { name: "asc" } });6 7 return (8 <ul>9 {courses.map((c) => (10 <li key={c.id}>{c.name}</li>11 ))}12 </ul>13 );14}1/3Importing a database client is fine here, since this code only runs on the server.
A database query right inside the component. The db library and your credentials stay on the server, and only the list HTML is sent.
Save yourself the pain
Common mistakes
Oops
Adding useState to a Server Component and getting a confusing error.
Do this instead
Move the interactive part into its own file with "use client" at the top.
Oops
Building an API route just so your own page can fetch from it.
Do this instead
A Server Component can call the database or function directly. Skip the extra trip.
Your mission
Fetch without useEffect
Quick check
Where does console.log inside a Server Component show up?
Go deeper
- 1Identify which components in a small app could be server components (no interactivity).
- 2Fetch data directly inside a server component with `async`/`await` — no `useEffect` needed.
- 3Learn they can't use hooks, browser APIs, or event handlers.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.