Fulldev UI is distributed as a shadcn-compatible @fulldev registry for Astro
projects. The setup below keeps your project aligned with the examples in this
documentation.
If your project already has a components.json, do not run init again,
because it replaces the theme tokens in your stylesheet. Add the @fulldev
registry below to components.json instead, then run
npx shadcn@latest add @fulldev/init. It adds the class helper, dependencies,
and base styles, and leaves your theme tokens and colors alone.
Fulldev UI serves the Base UI styles only. If the style in your
components.json is a legacy style such as new-york, or starts with
radix-, set it to a Base UI style such as base-vega first. See
Presets.
Add to existing Astro project
Edit tsconfig.json file
Add the following code to the tsconfig.json file to resolve paths:
{
"compilerOptions": {
// ...
"paths": {
"@/*": [
"./src/*"
]
}
// ...
}
}
Initialize Fulldev UI
Fulldev UI uses the shadcn CLI. Initialize your project from the Fulldev UI base:
npx shadcn@latest init https://ui.full.dev/r/styles/base-vega/base.json
This writes components.json with the @fulldev registry, adds the theme
tokens to your stylesheet, and installs the class helper and dependencies. Your
stylesheet is the one components.json points to, src/styles/global.css by
default. Import it from your app layout.
Replace base-vega with another shadcn/ui style, such as base-nova, to start
in that style. To use a shadcn/ui preset, see Presets.
The @fulldev registry in components.json looks like this. The CLI fills in
{style} from the style in components.json, so components install in your
project’s style:
{
"registries": {
"@fulldev": "https://ui.full.dev/r/styles/{style}/{name}.json"
}
}
Install every block with npx shadcn@latest add @fulldev/blocks, or choose
individual blocks and components below.
Use a container-aware app shell
Fulldev UI uses Tailwind CSS v4 container query variants such as @2xl: and @max-5xl:. These are intentional and should not be converted to viewport breakpoints like 2xl:.
To make those variants work, add @container to the root wrapper that contains your page content:
---
import "@/styles/global.css"
---
<body class="@container">
<slot />
</body>
Add Components
You can now start adding components to your project.
npx shadcn@latest add @fulldev/button
or multiple resources at once:
npx shadcn@latest add @fulldev/button @fulldev/card @fulldev/section
Add all components
npx shadcn@latest add @fulldev/components
Usage
The commands above will add components to your project. You can then import them like this:
---
import { Button } from "@/components/ui/button"
---
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>Astro + Fulldev UI</title>
</head>
<body class="@container">
<div class="grid h-screen place-items-center content-center">
<Button>Button</Button>
</div>
</body>
</html>
At that point, you can follow the component pages directly and install only the pieces you need.
Data Slot 1.x upgrades
Interactive components require Data Slot 1.0.2 or newer within 1.x. Updating npm versions alone does not update component files previously copied by the registry. Reinstall the affected registry items and merge their source changes with your customizations.
Components use Data Slot’s own initialization. In projects using Astro’s
ClientRouter, they release their controllers before it swaps the page. Component state is reinitialized on navigation;
this integration does not preserve interactive state across transition:persist.
Select, Tooltip, Hover Card and Navigation Menu now use Data Slot’s recommended
lazy mounting. Closed content is retained outside the document. This changes DOM
queries compared with 0.2.x: use mountStrategy="eager" if custom code needs to
query closed content. Nested Data Slot components initialize in either mode.
CommandDialog already includes a Dialog root. Use its trigger slot instead of
wrapping it in another Dialog. See the Command example.
Command inputs inside dialogs should use native autofocus to receive initial
focus. Standalone command inputs leave page focus unchanged. Slider now follows
Data Slot’s centered thumb default; use thumbAlignment="edge" to retain edge
alignment. Tabs triggers and panels require an explicit value.
Buttons and Tabs triggers default to type="button", matching shadcn controls.
Use type="submit" explicitly for form submission.