React introduced two special keywords: use client
and use server
.
These help developers cleanly connect frontend and backend code—almost like you're writing one single program that runs across two machines.
We need to think of Client and Server Components as two doors.
use client
= lets the server send code to the client (as a <script>
).
use server
= lets the client call functions on the server (like a fetch
).
These directives make this interaction part of your code structure. Instead of treating backend and frontend as completely separate, these tools let you import and export code across that boundary in a structured, predictable way.
use server
:Imagine your backend has a function to "like a post":
'use server';
export async function likePost(postId) {
// store like in the database
}
On the frontend, instead of writing a fetch() manually, you just do:
import { likePost } from './backend';
await likePost(postId); // Automatically turns into a fetch
React handles turning that import into an HTTP request to the server for you.
Dan argues that this server and client model is as fundamental as if/else, async/await, or first-class functions. It makes client-server apps:
You're no longer writing two separate apps that talk over REST APIs. You're writing one unified program that runs in two places.
Now flip the situation.
You want your server-rendered page to include a Like button that runs client-side JS when clicked. In old days, you had to manually include a <script>
and write JS separately.
Instead, you can now write:
'use client';
export function LikeButton({ postId, liked }) {
return <button>{liked ? 'Unlike' : 'Like'}</button>;
}
Then, in your server code:
import { LikeButton } from './LikeButton';
return (
<html>
<body>
<LikeButton postId={123} liked={true} />
</body>
</html>
);
React turns that into a script that runs on the client and handles the interactivity.
✅ Server sends HTML ✅ Client takes over interactivity ✅ Easy to pass data from server to client