Compose components

Compose instead of wrapping everything

Combine focused component parts in application code and avoid building a second rigid abstraction layer over the generated source.

8 minute lesson

~~~

Many shadcn components expose related parts, such as CardHeader, CardContent, and CardFooter. You arrange those parts to match the interface you need.

Create application components for repeated product concepts, not one wrapper for every UI primitive. A ProjectCard can compose Card and Button because it represents a real object. A MyButton wrapper that only renames every Button prop usually creates indirection without adding meaning.

Use three levels deliberately. Primitive components own reusable interaction and visual contracts. Compositions arrange primitives for a recurring interface pattern. Domain components accept product data and actions, such as a project and an archive callback. Keeping these jobs distinct makes it clear where a change belongs.

Prop mirroring is a warning sign. If a wrapper accepts every Button prop plus several exceptions, callers must understand two APIs and upgrades must preserve both. A focused domain component can expose project, onOpen, and onArchive because those names describe the product rather than the underlying library.

Add Card and build a ProjectCard with a name, description, status, and actions outside components/ui. Change the underlying Card spacing and the product’s archive wording separately; each edit should have one obvious owner and should not require forwarding arbitrary primitive props.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →