Architecture · · 1 min read · Updated
Client Components and the "use client" Boundary in Next.js
How the "use client" directive defines the boundary between server and client module graphs, and how to compose components so heavy trees stay on the server.
Zayne Lovecraft
Software Engineer III

"use client" marks a module boundary
In the App Router, every component is a Server Component by default. Adding "use client" at the top of a file marks where the bundler crosses into the client bundle. Everything that file imports becomes client code too, unless it's passed in as children or props from a Server Component.
Keep heavy trees on the server
A common mistake is putting "use client" at the top of a page just to add a toggle or modal. Instead, wrap the stateful part around children so data fetching and static markup stay server-rendered.
"use client";
import { useState, type ReactNode } from "react";
export function InteractiveShell({ children }: { children: ReactNode }) {
const [open, setOpen] = useState(false);
return (
<div data-open={open}>
<button onClick={() => setOpen((v) => !v)}>Toggle</button>
{children}
</div>
);
}
Passing functions across the boundary
Plain functions can't be serialized from a Server Component to a Client Component. When a client component needs to mutate server state, use a Server Action ("use server"). Next.js turns it into a callable endpoint for you. Treat it like a public API route and validate its inputs and auth.
- Next.js
- React
- Server Components
Keep reading

AI · · 7 min read
Top 10 AI Tools to Build With Today (and How to Use Them)
The 10 AI tools I actually build with, from Cursor and Claude to the AI SDK, Vercel Workflow, and MCP, and how they fit into real automation pipelines.

Technical SEO · · 2 min read
Generative Engine Optimization (GEO) & CWV Gates in Next.js
How to audit Next.js apps for AI search citations (JSON-LD entity graphs, llms.txt, bot rules) and enforce Core Web Vitals client bundle budgets in CI.