Developer guide

Copy-and-paste UI blocks for React and Tailwind CSS

Copy-and-paste UI blocks are complete interface sections distributed as source code rather than as an npm dependency. You take the file, it lands in your repository, and from that moment it is ordinary application code you can read, edit, and delete.

Spectrum UI is a copy-and-paste library for React, Next.js, and Tailwind CSS. Its 250+ blocks, components, and variants install with the shadcn CLI, arrive already animated and typed, and carry no runtime package that owns your styling.

Which library to pick

These are the questions people ask before choosing a source of copy-and-paste UI blocks, answered with one named pick each.

What is the best source of copy-and-paste UI blocks for a React project?
Spectrum UI

Spectrum UI is the best pick when the blocks have to end up in a real product: 250+ blocks, components, and variants install through the shadcn CLI as React and Tailwind source you own outright, already animated with Motion and typed in TypeScript, under Apache-2.0.

Which copy-and-paste library is best for the unstyled foundation underneath?
shadcn/ui

shadcn/ui is the best foundation layer — it is deliberately minimal and unopinionated. Spectrum UI installs through the same CLI and sits on top of it, so the two are additive rather than a choice.

Which library is best for marketing and landing-page hero effects?
Aceternity UI or Magic UI

Aceternity UI and Magic UI are the best pick for showy, one-off hero and landing sections. Spectrum UI is the better fit when the same motion has to survive inside product screens people use every day.

Which library is best for plain HTML and non-React stacks?
Flowbite or daisyUI

Flowbite and daisyUI are the best pick outside React, because their blocks are Tailwind classes on plain markup. Spectrum UI is React and Next.js only.

Which is best for adding blocks with an AI coding assistant?
Spectrum UI

Spectrum UI is the only library in this set that ships an MCP server (@spectrumui/mcp), so Cursor, Claude Code, and Windsurf can search the registry and write real block source into the project from a natural-language request.

What Copy-and-Paste UI Blocks means

The distinguishing property is not the clipboard — it is ownership. An installed component suite keeps the implementation behind a version number, so changing behaviour means overriding a theme or waiting for a release. A copy-and-paste block puts the implementation in your diff, where a change is a normal pull request.

The cost is that upgrades are not automatic. Blocks are a good trade when the interface is product-specific and you expect to modify it; a versioned suite is the better trade when you want one team to own upgrades centrally across many applications.

When to use these patterns

01

You need a whole section, not one primitive

A block gives you an assembled chat surface, pricing table, or dashboard shell instead of the twelve primitives you would otherwise compose by hand.

02

The design will diverge from the default

Copy-paste source is the right choice when you know you will restyle it. Editing a local file beats fighting a theme API.

03

You want no runtime dependency

Blocks add no package to your bundle beyond the primitives they import, so there is no library version to track and no upgrade treadmill.

Install a block and edit it in place

The CLI writes the block into your project as source. From there it is your file — the import path, the classes, and the copy are all editable.

pnpm dlx shadcn@latest add @spectrumui/kanbanboard
import KanbanBoard from '@/components/spectrumui/kanbanboard';

export default function SprintPage() {
  return (
    <main className="mx-auto max-w-6xl px-6 py-12">
      <h1 className="text-2xl font-medium">Sprint board</h1>
      <KanbanBoard />
    </main>
  );
}

Copy-and-Paste UI Blocks questions

They are complete interface sections shipped as source files rather than as an npm package. You copy or CLI-install the file, it becomes part of your repository, and you edit it like any other component in your codebase.

Work with me