How to Add a Card to a React App
Step-by-step guide to adding a copy-and-own Card to any React project with the Drivn CLI — zero runtime deps, compound Preview/Info slots, and pure Tailwind.
A card is the workhorse of almost every interface — product tiles, dashboard panels, settings rows, gallery items. The markup is simple, but doing it consistently is not: you end up repeating the same border radius, the same divider between the visual area and the label row, the same hover lift on dozens of surfaces. A small component fixes that, as long as it stays flexible enough to hold anything.
Drivn takes the copy-and-own route instead of shipping a runtime package. The CLI writes the Card source straight into your repo, and that source has no third-party dependencies at all — no Radix, no cva, not even an icon import. It is pure React plus Tailwind, with every class held in a single const styles object. The component is a compound built with Object.assign: a Card root plus Card.Preview and Card.Info slots, so one import gives you the whole structure. And because there are no hooks and no 'use client' directive, the Card renders inside a Next.js Server Component with no client boundary.
This guide walks through adding the Card to an existing React app in a few minutes — install the CLI, copy the component, render the root, and compose the Preview and Info slots. It works the same in a Vite + React project, a Next.js App Router app, or any framework with Tailwind and TypeScript. For broader setup see the installation page; for the Next.js specifics see the Next.js Card guide; for live patterns see the Card examples page.
Prerequisites
Before installing the Card, make sure your React project has the three things Drivn assumes: Tailwind CSS v4 installed and processing your CSS, TypeScript configured (the component ships as a .tsx file), and a @/ path alias pointing at your source directory. If you scaffolded with create-next-app, npm create vite, or npx drivn@latest create, all three are already wired up. For a custom setup, open your tsconfig.json and verify the compilerOptions.paths entry; the installation page lists the minimal viable config. The Card is unusually light on dependencies — it imports only React and the local cn class-merge helper, with no icon library and no runtime UI package, so there is nothing extra for the CLI to add. No PostCSS plugins, Babel presets, or Tailwind config changes are required.
Step 1 — Install Drivn via the CLI
Run the CLI from your project root to add the Card source file. The command prompts once for your install directory (defaulting to src/components/ui/), then writes card.tsx. Because the Card has no runtime dependencies, nothing is added to your package.json — the only change is one new file in your repo. No global config file is created; the Card is just a TypeScript file you can edit like any other component. Confirm the file landed correctly in your editor, then commit the change. If your project uses a monorepo layout or a non-standard path, the CLI docs cover the flags used to target a custom location during install.
1 # add the Card to your existing React project 2 npx drivn add card 3 4 # verify the file was written 5 ls src/components/ui/card.tsx
Step 2 — Import and render the Card
Open the page where the Card should live and import it from your UI directory. A single import line gives you the root and both slots through dot notation — Card, Card.Preview, and Card.Info. The root renders a fixed-size square surface by default (w-48 aspect-square) with a bg-card background, a border-border outline, and a rounded-[20px] radius. Because the Card has no hooks and no 'use client' directive, it renders inside a Next.js Server Component without a client boundary. See the Card docs for the full prop table and the examples page for complete patterns.
1 import { Card } from '@/components/ui/card' 2 3 export function Tile() { 4 return ( 5 <Card> 6 <Card.Preview> 7 <span>Preview content</span> 8 </Card.Preview> 9 <Card.Info> 10 <span>Card title</span> 11 </Card.Info> 12 </Card> 13 ) 14 }
Step 3 — Compose the Preview and Info slots
The two slots split the card into a visual area and a label row. Card.Preview is the top section — flex-1 flex items-center justify-center with a border-b border-border divider and p-6 padding — so whatever you drop in (an emoji, an icon, an image, a chart) sits centered above the line. Card.Info is the bottom row — p-5 flex justify-between items-center — built to hold a title on the left and an action or badge on the right. Both accept a className so you can override padding or alignment per instance without touching the source. The compound shape means you only ever import Card; the slots come attached to it via Object.assign.
1 <Card> 2 <Card.Preview> 3 <span className="text-2xl">��</span> 4 </Card.Preview> 5 <Card.Info> 6 <div> 7 <p className="text-sm font-semibold text-foreground">Card Title</p> 8 <p className="text-xs text-muted-foreground">Description text</p> 9 </div> 10 </Card.Info> 11 </Card>
Step 4 — Customize the styles object
Because the Card lives in your codebase, customization is a source edit rather than a prop API. Open src/components/ui/card.tsx and find the const styles object near the top — it holds every class the component uses, grouped into base, hover, preview, and info. Widen the card by changing w-48 in base, soften the corners by editing rounded-[20px], or adjust the slot padding in preview and info. The hover lift — hover:bg-accent hover:border-border hover:-translate-y-1 — is opt-out per instance via the hover={false} prop on the root, or remove it globally by deleting the hover key. To re-theme every card at once instead, change the tokens it references — bg-card, border-border, bg-accent — in your theme tokens.
1 // src/components/ui/card.tsx — styles object 2 const styles = { 3 base: cn( 4 'w-48 aspect-square flex flex-col', 5 'bg-card border border-border rounded-[20px]', 6 'overflow-hidden transition-all duration-200' 7 ), 8 hover: 'hover:bg-accent hover:border-border hover:-translate-y-1', 9 preview: cn( 10 'flex-1 flex items-center justify-center', 11 'border-b border-border p-6' 12 ), 13 info: 'p-5 flex justify-between items-center', 14 }
Install Drivn in one command
Copy the source into your project and own every line. Zero runtime dependencies, pure React + Tailwind.
Frequently asked questions
Yes. Set your CRA project up with TypeScript and Tailwind v4 first, then run the Drivn CLI. Tailwind v4 has a short install guide, and a tsconfig.json in place is enough for the CLI to drop the .tsx component into your project. The Card has no dependency on React Router, Next.js, or any framework-specific API — it is a plain layout component that renders anywhere React and Tailwind render to the DOM.
None. The Card source imports only React and the local cn class-merge helper — no Radix, no cva, no icon library, no floating-ui. That makes it one of the lightest components Drivn ships: installing it adds a single .tsx file to your repo and nothing to your package.json. The structure is plain <div> elements and the styling is entirely Tailwind classes held in a styles object.
Pass hover={false} on the Card root. The root applies the hover style — hover:bg-accent hover:border-border hover:-translate-y-1 — only when the hover prop is true, which it is by default. Setting it false renders a static card with no lift or background change, which suits non-interactive panels. To remove the effect everywhere, delete the hover key from the styles object in your copy of the source.
Yes. The Card is built from plain <div> elements with no useState, no useEffect, and no 'use client' directive, so it renders directly inside a Server Component with no client boundary. You can compose it freely in server-rendered pages and data-driven grids; only the interactive children you place inside it — a button, a link with a handler — pull in client behavior at their own call site.

