Server Components

In the App Router every component is a Server Component by default — it runs on the server and ships no JavaScript.

The App Router is built on React Server Components (RSC). By default, every component you write is a Server Component: it runs on the server, can access back-end resources directly, and sends only rendered HTML to the browser — no component JavaScript at all.

The boundary between Server Components and Client Components Server Components (default — run on the server) • fetch data directly • read databases / secrets • zero JS shipped • no useState / onClick Client Components ("use client" — run in browser) • useState / useEffect • onClick, onChange • browser APIs • hydrated with JS "use client" crossing the boundary once opts that component and its imports into the client
Server Components are the default; add "use client" only where interactivity is needed.

What Server Components can do

  • Fetch data with await right inside the component.
  • Read databases, files, and secret environment variables safely.
  • Keep large dependencies on the server, out of the client bundle.

What they cannot do: use state, effects, or browser event handlers. For that you need a Client Component.

Example

Example · typescript
// app/page.tsx  — a Server Component (the default)
export default async function Page() {
  const res = await fetch('https://api.example.com/stats');
  const data = await res.json();
  return <p>Total users: {data.users}</p>;
}

When to use it

  • A product listing page fetches inventory data directly in a Server Component so no data-fetching code is sent to the browser.
  • A blog layout reads a database for the author bio in a Server Component, keeping database credentials server-side only.
  • An admin dashboard renders heavy analytics charts as Server Components to reduce the client JavaScript bundle.

More examples

Server component with DB query

The db call runs only on the server — credentials never reach the browser and no extra client bundle is added.

Example · ts
// app/products/page.tsx  (Server Component by default)
import { db } from '@/lib/db';

export default async function ProductsPage() {
  const products = await db.product.findMany();
  return (
    <ul>
      {products.map(p => <li key={p.id}>{p.name}</li>)}
    </ul>
  );
}

No useState needed for data

Server Components eliminate useEffect data-fetching boilerplate because they are async functions.

Example · ts
// app/weather/page.tsx
export default async function WeatherPage() {
  const res = await fetch('https://wttr.in/?format=j1');
  const data = await res.json();
  const temp = data.current_condition[0].temp_C;
  return <p>Current temp: {temp}°C</p>;
}

Server component accepting props

Any async component without 'use client' is a Server Component, composable in pages and layouts.

Example · ts
// components/UserCard.tsx  (Server Component)
import { getUser } from '@/lib/users';

export default async function UserCard({ userId }: { userId: string }) {
  const user = await getUser(userId);
  return <div>{user.name} — {user.email}</div>;
}

Discussion

  • Be the first to comment on this lesson.