How to Add a Separator to a React App
Step-by-step guide to adding a separator to any React app with the Drivn CLI — a copy-paste, server-safe divider themed by one border token, zero deps.
Reaching for a separator means part of your React UI needs a visual break — a hairline between a card's header and its body, a divider inside a dropdown menu, a thin rule between two columns of a toolbar. You could drop a bare <div className="h-px bg-gray-200" /> inline every time, but that scatters a hardcoded color through your markup, skips the role="separator" that assistive tech relies on, and gives you nothing reusable when the divider needs to run vertical instead.
Drivn solves it by copy-paste: the CLI writes a separator.tsx file into your repository. The Separator is purely presentational — a single <div> with role="separator" whose class is picked from a two-key styles object by an orientation prop. It holds no state and calls no browser API, so the file ships without a 'use client' directive and renders anywhere, server or client. It imports nothing past React and the local cn utility, so there is no package to version-lock and nothing to configure.
This guide adds the Separator to any React app — install the CLI, render a horizontal divider, stand a vertical rule up inside a flex row, and restyle the line from the one styles object you own. It works the same in Vite + React or Next.js. For the App Router walkthrough see the Next.js Separator guide, and for copy-paste layouts see the Separator examples.
Prerequisites
Before installing Separator, confirm your React project has the two things Drivn assumes: Tailwind CSS v4 installed and processing your styles, and a @/ path alias pointing at your source directory (the component ships as a .tsx file, so TypeScript is part of the stack). If you scaffolded with create-next-app, npm create vite, or npx drivn@latest create, both are already wired; for a custom setup the installation page lists the minimal config. The Separator is the smallest install in the library — its only import past React is the local cn utility for class merging, so there is no third-party package to add. The one thing worth knowing before you render it is that the line takes its size from its parent: a horizontal rule spans its container's width with w-full, and a vertical rule fills its parent's height with h-full, so the element you wrap it in decides how far the divider runs.
Step 1 — Install Drivn via the CLI
Run the CLI from your project root to add the Separator source file. The command prompts once for your install directory (defaulting to src/components/ui/) and writes a single separator.tsx — no other files, because the component has no peer dependency beyond React and the cn utility. No global config file is created; the result is TypeScript source you edit like any other component. Confirm it landed in your editor, then commit it for a clean baseline. If your project uses a monorepo layout or a non-standard source path, the CLI docs cover the flags for targeting a custom location during install. Because the file is yours after install, future Drivn releases will not overwrite your edits.
1 # add the Separator source file 2 npx drivn add separator
Step 2 — Render a horizontal separator
Import Separator and drop it between two blocks of content. With no props it defaults to orientation="horizontal", which applies w-full h-px bg-border — a one-pixel rule that stretches across the full width of its parent. Because the width comes from w-full, the parent element decides how wide the line runs: put the divider inside a fixed-width card or a padded section and it spans exactly that box. The underlying <div> carries role="separator", so assistive technology announces it as a divider rather than skipping past it as empty markup — the grouping you see is the grouping a screen reader hears. Since the component holds no state, you can render it in a Server Component or a client component with no boundary to think about. Pair it with a Card to split a header from its body.
1 import { Separator } from '@/components/ui/separator' 2 3 export function AccountHeader() { 4 return ( 5 <div> 6 <h3 className="font-medium">Account</h3> 7 <Separator /> 8 <p className="text-sm text-muted-foreground"> 9 Manage your profile and settings. 10 </p> 11 </div> 12 ) 13 }
Step 3 — Make it vertical inside a flex row
Pass orientation="vertical" to switch the rule from a horizontal line to a vertical one. The component reads that prop and swaps styles.horizontal for styles.vertical — h-full w-px bg-border — a one-pixel-wide line that fills its parent's height instead of its width. The catch mirrors the horizontal case: a vertical separator needs its parent to give it a height to fill, so it belongs inside a flex row where the row's height defines the line. Set the container to flex items-stretch (or give the separator an explicit h-* through className) so the rule runs the full height between the items it divides. This is the shape for a toolbar of icon buttons, a row of inline stats, or a nav-style row where a thin vertical rule reads cleaner than extra gap. If the line does not show, the parent has no height for h-full to resolve against — the most common vertical-separator mistake.
1 <div className="flex items-stretch h-8 gap-4"> 2 <span>Drafts</span> 3 <Separator orientation="vertical" /> 4 <span>Sent</span> 5 <Separator orientation="vertical" /> 6 <span>Archive</span> 7 </div>
Step 4 — Restyle and theme the separator
Every class the component renders lives in one small styles object at the top of the file you own — styles.horizontal is w-full h-px bg-border and styles.vertical is h-full w-px bg-border. The function looks up styles[orientation], merges it with any className through cn(), and renders the <div>. Make the rule bolder by bumping h-px to h-0.5 in styles.horizontal; recolor it by swapping bg-border for bg-primary/30; or add breathing room at a call site with a margin utility like my-4. The className you pass merges after the base style, so a single <Separator className="my-6 bg-primary/20" /> thickens, tints, or spaces one divider without touching the shared file. Because the default reads the --border theme token, adjusting that value in theming re-themes every separator across the app for dark and light mode at once. The verbatim source below is the whole component.
1 // verbatim from separator.tsx 2 const styles = { 3 horizontal: 'w-full h-px bg-border', 4 vertical: 'h-full w-px bg-border', 5 } 6 7 export function Separator({ 8 orientation = 'horizontal', 9 className, 10 }: SeparatorProps) { 11 return ( 12 <div 13 role="separator" 14 className={cn(styles[orientation], className)} 15 /> 16 ) 17 }
Install Drivn in one command
Copy the source into your project and own every line. Zero runtime dependencies, pure React + Tailwind.
Frequently asked questions
No. The Separator holds no state and calls no browser API — it is a styled <div> that maps an orientation prop to a Tailwind class. Its source ships without a 'use client' directive, so it renders straight inside a Server Component in the Next.js App Router and works the same in any client-rendered React app. Nothing about it forces a client boundary, which makes it free to drop into a server-rendered layout, card, or content page.
Pass orientation="vertical" to the Separator. The default horizontal applies w-full h-px bg-border; vertical swaps in h-full w-px bg-border through the two-key styles object. Then give the parent a height for the rule to fill — usually a flex items-stretch row — so the one-pixel line runs the full height between the items it divides. Without a height on the parent, a vertical separator has nothing to stretch against and stays invisible.
A vertical separator is h-full w-px, so it fills its parent's height — and if the parent has no height, h-full resolves to zero and the line is invisible. Put the separator inside a flex row with items-stretch and a defined height, or give the separator itself an explicit height like h-6 through className. This mirrors the horizontal case, where the line needs a parent width to span with w-full.
Yes. The separator is a <div> styled by two Tailwind strings in the styles object inside the file you own. Recolor it by editing bg-border, and thicken it by bumping h-px (horizontal) or w-px (vertical) to h-0.5 or w-0.5. Because the default reads the --border theme token, retheming that value updates every separator for dark and light mode at once. A one-off className merges after the base style, so one call site can restyle a single divider.
Yes. The component has no dependency on Next.js or any router — it is a self-contained styled <div> with no state, no context, and no browser API, so it works anywhere React and Tailwind reach the DOM. Set the project up with TypeScript and Tailwind v4 first, then run npx drivn add separator and render it the same way, defaulting to a horizontal rule or passing orientation="vertical" inside a flex row.

