Server Components vs Client Components
In plain React (ReactNotes / Vite), every component runs in the browser. In Next.js, every component is a Server Component BY DEFAULT โ it renders once on the server and ships to the browser as plain HTML, with zero JavaScript for that component included in the bundle.
Explain it like I'm 5
A Server Component is like a chef who cooks the meal in the kitchen (the server) and sends you the finished plate (HTML) โ you never see the recipe or the oven. A Client Component (anything with 'use client' at the top) is more like a meal-kit box: the ingredients and instructions ship to your kitchen (the browser) so YOU can interact with it โ stir it, change it, react to clicks.
1. This whole page is a Server Component
// app/server-components/page.tsx (no "use client")
export default async function ServerComponentsPage() {
const serverRenderedAt = new Date().toISOString()
return <p>Rendered on the server at: {serverRenderedAt}</p>
}Live result
Rendered on the server at: 2026-07-30T09:51:25.081Z
Refresh the page โ this timestamp updates every time, because this route re-renders on the server per request (see the SSR demo for more on that).
2. Interactivity requires 'use client'
// app/components/Counter.tsx
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount((c) => c + 1)}>{count}</button>
)
}Live result
3. Why default-to-server matters
// Fine in a Server Component โ this never reaches the browser bundle:
import { db } from '@/lib/database'
export default async function Orders() {
const orders = await db.query('select * from orders')
return <OrdersTable orders={orders} />
}
// NOT fine in a Client Component โ db would be bundled and its
// credentials/queries exposed to anyone reading the page's JS.