v0-3d-ui-library
A shadcn-style installable component library for 3D primitives in React.
Problem
Adding 3D to a React project means assembling a React Three Fiber scene manually — camera, lighting, geometry, and controls all configured individually. For developers who want one interactive 3D element in an otherwise standard app, the setup cost is disproportionate to the output. The shadcn/ui pattern — install a component, it works, customise via props — has no equivalent for 3D primitives.
Why it matters
Developer experience directly affects adoption. If the cost of adding one 3D element to a project is configuring an entire scene, most developers won't do it. Reducing setup to a single import and a few props makes 3D accessible to the standard React developer workflow.
Approach
Apply the shadcn/ui pattern to 3D primitives. Each component encapsulates a complete React Three Fiber scene. Consumers pass props — variant, size, animate, position, metalness, roughness, wireframe — without touching any Three.js configuration. The variant and size systems mirror shadcn/ui conventions so the API feels immediately familiar to any React developer.
Architecture
React Three Fiber for scene abstraction. Drei for camera controls, environment presets, and helper utilities. Class Variance Authority (CVA) for the variant and size system — same pattern as shadcn/ui. TypeScript throughout with fully exported prop interfaces. Installable as @3d-ui/components via npm.
Usage
import { Scene, Cube, Sphere } from "@3d-ui/components"
export function MyScene() {
return (
<Scene backgroundColor="#fafafa" environment="studio">
<Cube variant="primary" size="lg" animate position={[-1.5, 0, 0]} />
<Sphere variant="secondary" animate position={[1.5, 0, 0]} />
</Scene>
)
}Tradeoffs
The library covers geometric primitives. Complex meshes, custom geometries, and GLTF/GLB model loading are outside current scope. The variant system maps named presets to material configurations — an opinionated API that not every project will share. Raw metalness and roughness props provide an escape hatch without breaking the abstraction.
Learnings
Designing a developer-facing API is a different problem from designing a user-facing UI. The question shifts from "is this intuitive?" to "is this predictable to integrate?" Matching shadcn/ui conventions made this tractable — developers already have expectations about how variant and size props behave, and meeting those expectations reduces time to first working component.