Skip to content

Migrate · 1 of 3

Adopt Hoverlab in an existing project

Add blocks, pages and effects to an app that already runs. What to check first, what changes between Tailwind v3 and v4, exactly where the files land, and the two ways to install: our CLI, or the shadcn CLI you may already use.

Check three things first

QuestionWhy it mattersHow to tell
Is it React?Blocks, pages and primitives are React with Tailwind classes and ship as written — there is no Vue or Svelte port of a block. Effects are plain CSS and work anywhere.react or next in package.json. In a non-React project add still writes the files and says so.
Tailwind v3 or v4?The blocks use utility classes; how a token name like bg-card becomes one differs between the two.Next section.
Does @/ resolve?A page imports its blocks as @/components/{id}. If your alias points somewhere else, the imports fail at build time — not at install.paths in tsconfig.json. With a src/ folder it should be "@/*": ["./src/*"]; without one, "@/*": ["./*"].

Tailwind v3 or v4

Tailwind v3Tailwind v4
How to telltailwindcss 3.x, a tailwind.config.* file, and @tailwind base; in your CSS.tailwindcss 4.x, @import "tailwindcss"; in your CSS, and usually no config file.
Where bg-card comes fromtheme.extend.colors in tailwind.config.A @theme block in your CSS.
Finding the files you addcontent must list the folders they land in, or the classes are never generated.Automatic. There is no content list to keep.
What Hoverlab ships for itEvery scaffolded template is v3 — a tailwind.config.ts plus @tailwind directives — and the token export has a v3 file.This site runs v4, so every block preview you see here is a v4 render. The token export has a v4 file, and the registry presets are v4-style.

The CLI does not read your Tailwind version. It looks for tailwindcss in your dependencies only to decide what format to write an effect in, and it never edits your config or your stylesheet. So an installed block compiles under either major, provided your project defines the token names it uses. Without them bg-card generates no CSS and the block renders unstyled. That step is the tokens guide.

Blocks were written with the v3 spelling of four utilities whose defaults v4 moved by a step: shadow-sm, rounded-sm, ring and outline-none. Under v4 they still work and look fractionally different. Nothing in the block, page or primitive sources uses a utility v4 removed or one that only v4 has — that is checked by a test against the source, so it stays true. It is not the same as having tried every block in every v4 project.

Install with the CLI

terminal
# what would be written — writes nothing
npx hoverlab add pricing-tiers --dry-run

# for real
npx hoverlab add pricing-tiers

# a page, plus every block it imports
npx hoverlab add checkout-page

# an effect, into a folder you choose
npx hoverlab add btn-gradient --dir src/styles/effects
You addLands atNote
A block or primitivecomponents/{id}.tsxUnder src/ if your project has src/app, src/components or src/pages; at the project root otherwise. Not a preference — pages import blocks by this path.
A pageapp/{id}.tsxA file under app/, not a route yet. Move it to app/your-route/page.tsx — it has a default export — and its blocks come with it into components/.
An effectA hoverlab/ folder inside your components or styles directoryOutput follows your project: React, Vue, Svelte, plain CSS or Tailwind utilities.

--dir overrides the destination. For a block or page it is the root the components/… and app/… paths hang from; for an effect it is the folder the CSS lands in.

If a block needs a package you do not have, add prints the npm i line for it and does not run it. Nothing is installed behind your back.

What hoverlab.lock.json records

Every real add writes a record of what it installed, in the directory you ran it from, so outdated, diff and update have something to compare against later. It is meant to be committed.

hoverlab.lock.json
{
  "lockfileVersion": 1,
  "artifacts": {
    "pricing-tiers": {
      "level": "block",
      "revision": "3fa9c01b7d2e",
      "installedAt": "2026-09-21",
      "files": ["components/pricing-tiers.tsx"],
      "hashes": {
        "components/pricing-tiers.tsx": "sha256:…"
      }
    }
  }
}
  • revision is a fingerprint of the file bodies — not their paths, not the catalog metadata — so moving a file does not make it look stale.
  • hashes are SHA-256 of each file exactly as it was written. They are how update proves you have not edited a file.
  • Paths are relative and forward-slashed, and there is no absolute path, user name or timestamp beyond the install date, so a lockfile committed on Windows reads correctly in CI.
  • framework is recorded for effects only — the catalog generates an effect per framework, and comparing your React copy against the CSS version would report the whole file as changed.
Only add writes it. hoverlab init scaffolds a template without recording it, and so does npx shadcn add. Those files are yours from the first minute, but outdated cannot see them. The updates guide covers how to bring one under tracking.

Or with npx shadcn add

If your project already uses shadcn/ui, you do not need our CLI. The catalog is a public registry, so point components.json at it once:

components.json
{
  "registries": {
    "@hoverlab": "https://hoverlab5.netlify.app/r/{name}.json"
  }
}
terminal
npx shadcn add @hoverlab/pricing-tiers
npx shadcn add @hoverlab/checkout-page

The index is /registry.json. Setup and search are in the registry docs; what follows is what changes when the project is not new.

npx hoverlab addnpx shadcn add @hoverlab/…
A page lands atapp/{id}.tsx, a file to moveapp/{id}/page.tsx, already a route
Your tokensUntouched. You wire them, per the tokens guide.@hoverlab/hoverlab writes them — and replaces any of yours with the same names.
Update trackingRecorded in hoverlab.lock.jsonNot recorded.
NeedsNode. No config.A components.json in your project.
Read this before installing the base item. npx shadcn add @hoverlab/hoverlab writes finished colours — oklch(…) values — into :root and .dark, replacing any variable of the same name. If your Tailwind v3 config wraps those variables as hsl(var(--primary)), an oklch value inside it is not a colour and the utility stops working. Either skip the base item and keep your tokens, or move to var(--primary) first. We have not tested the shadcn CLI against a v3 project, so treat that path as unverified. The tokens guide explains the two formats.

After the install

terminal
git status                 # exactly what was written
npm run build              # does it compile?
npx hoverlab review        # accessibility, RTL, reduced-motion — on what you changed

review reads your uncommitted changes — the files you just added included — and runs entirely on your machine.

add also reports the ids it installed, so the catalog can rank what is being used. Nothing else about your project is in that request, and setting HOVERLAB_NO_TELEMETRY=1 turns it off.

Which licence you are on

Free licence. Everyone gets this, with or without an account. It covers learning, side projects and anything you are not paid for.

Commercial licence. Included with Pro, Studio, Enterprise and Team. It covers work you are paid for — client projects, products that charge money, anything shipped under a company name.

Adopting a block into a client project or a product you sell is the second case. The terms are on the licence page and the price is on pricing.

Something wrong or missing here? Browse the catalog — every page in it links back to the source it documents.