MENACEUI

Rendering architecture

RSC vs Client Components for Animated UI

Choose a React Server Component or client component boundary for animated UI based on state, browser APIs, event handling, and shipped JavaScript.

Reviewed 2026-09-01

Use capability as the boundary test

A component needs a client boundary when it uses state, effects, event handlers, browser APIs, or a client-only animation library. Static markup does not become a client component merely because CSS animates it. Start with a Server Component and move the smallest interactive subtree across the boundary.

RequirementLikely boundary
Fetch data and render static copyServer Component
CSS hover, focus, or keyframe effectServer Component can emit the markup
Selection state, drag, or pointer trackingClient component
ResizeObserver, matchMedia, or requestAnimationFrameClient component

Pass serializable inputs into the island

Load data in the route, shape it on the server, and pass the client component the fields required for interaction. Avoid moving a data request into an effect just because the final control animates.

  • Pass strings, numbers, booleans, arrays, and plain objects.
  • Keep server-only credentials and provider clients out of props.
  • Handle mutations through the application’s established server boundary.
  • Render an understandable initial state before hydration.

Keep the directive low in the tree

Placing "use client" on a page or broad layout pulls its imported subtree into the client module graph. Prefer a dedicated wrapper around the interactive control. The server page can still render headings, documentation, media, and related links.

Animated Tabs needs a client boundary for selection and keyboard behavior. The article or dashboard that contains it does not need to become client-rendered.

Plan the pre-hydration state

Server-rendered markup may appear before event handlers attach. The initial selected tab, open state, and motion transform should match the client’s first render. Reading viewport or storage state during render can cause a mismatch; defer it to an effect or provide a stable server fallback.

Browser preferences such as reduced motion also need a stable first state. Do not hide critical content while waiting to read a media query.

Review checklist

  • Remove client directives from ancestors that do not need them.
  • Confirm props crossing the boundary are serializable.
  • Compare server markup with the first hydrated frame.
  • Measure shipped JavaScript and interaction delay in production.
  • Replay keyboard and reduced-motion behavior before release.