In the App Router, every component is a Server Component by default. Server Components render on the server and send the resulting HTML to the browser, which means they can directly read files, query databases, and call internal services without ever exposing secrets or backend logic to the client. Because they execute on the server, they do not support React hooks, browser-only APIs, or event listeners; they are intended for fetching data and producing static markup that can be cached and streamed efficiently.
When interactivity is required, you can opt into a Client Component by adding the directive "use client" at the top of the file. Client Components run in the browser and unlock the full React toolkit, including state via useState, side effects via useEffect, event handlers like onClick and onChange, and any browser API such as localStorage or window. The rule of thumb is to keep components as Server Components whenever possible, and only cross the boundary into a Client Component when the feature truly demands interactivity or browser access.
Because Server and Client Components live in the same tree, it is helpful to think of the App Router as a layered system. A Server Component can import and render a Client Component, but the reverse is not possible without careful handling: passing non-serializable values such as functions across the boundary is not allowed. Understanding this mental model helps you decide where to draw the line between server and client logic, and it explains why many common patterns, such as forms wired to Server Actions, can remain largely server-driven while still feeling fully interactive to the user.