Skip to content

shadcn.io is an independent project built on shadcn/ui

Laravel

Add shadcn.io components to Laravel's React starter kit: run init with our preset from the app's root, keep the kit's pages working, and add components.

Laravel's React starter kit is Inertia with React 19, TypeScript and Tailwind CSS v4, and it already ships shadcn/ui's components on Radix UI. The shadcn CLI doesn't create Laravel apps, so start with Laravel's installer, then switch the project to our preset.

Set up the React starter kit

Create the app

laravel new my-app --react

Without --react, choose the React starter kit when the installer asks. Skip this step if you already have a Laravel app with Inertia and React. Then:

cd my-app

Run init from the app's root

shadcn CLILocked
Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

The kit has a components.json already, so the CLI asks two things:

  • Overwrite components.json? Yes: it now points at our registry's theme.
  • Re-install existing UI components? No: the kit's login, settings and layout pages use the components it came with, and keeping them keeps those pages as they are.

Our theme goes into resources/css/app.css, and the paths stay the kit's: components in resources/js/components/ui, imported through @/, which points at resources/js.

Add components from the Radix UI folder

shadcn CLILocked
Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

The kit's pages write asChild on its components, the Radix UI way. Our Radix UI items keep that API, so when one replaces a component the kit already has (button, dialog, dropdown-menu…), its pages keep working. Base UI items (/r/<name>.json) use render instead; take them in an app without the kit's pages, or update those pages when you switch.

Use it in a page

resources/js/pages/settings/notifications.tsx
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";

export default function Notifications() {
  return (
    <div className="flex items-center gap-3">
      <Switch id="weekly-digest" />
      <Label htmlFor="weekly-digest">Weekly digest</Label>
    </div>
  );
}

Inertia forms

Inertia's useForm keeps the values and Laravel's validation errors; the components draw them. A text field with its server-side error:

resources/js/pages/profile/edit.tsx
import { useForm } from "@inertiajs/react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";

export default function EditProfile() {
  const { data, setData, patch, processing, errors } = useForm({ name: "" });

  return (
    <form
      className="flex max-w-sm flex-col gap-3"
      onSubmit={(event) => {
        event.preventDefault();
        patch("/profile");
      }}
    >
      <Label htmlFor="name">Name</Label>
      <Input
        aria-invalid={Boolean(errors.name)}
        id="name"
        onChange={(event) => setData("name", event.target.value)}
        value={data.name}
      />
      {errors.name ? (
        <p className="text-destructive text-sm">{errors.name}</p>
      ) : null}
      <Button disabled={processing} type="submit">
        Save
      </Button>
    </form>
  );
}

errors holds the messages from the controller's $request->validate(), keyed by field, after a failed submit.

FAQ

Why isn't there an init -t laravel like the other frameworks?

The shadcn CLI can't create a Laravel app: that takes PHP, Composer and Laravel's installer. Create the app with laravel new, then run init from its root.

Should I re-install the kit's components when init asks?

No. The kit's pages are written against the components it shipped, with Radix UI's asChild. Keep them, and replace one only when you add ours with the same name, from the Radix UI folder so the API stays the same.

Can I use the Base UI components in a Laravel app?

Yes, in an app without the kit's pages, or once you've updated those pages: Base UI components take a render prop where Radix UI's take asChild. Mixing both in one components/ui folder breaks whichever pages expect the other API.

Where do the components go in a Laravel project?

In resources/js/components/ui, with cn in resources/js/lib/utils.ts. The @/ alias points at resources/js: the kit sets it in tsconfig.json, and Laravel's Vite plugin resolves it.

Where is the theme?

In resources/css/app.css, the stylesheet Vite builds with Tailwind CSS v4. init replaces the kit's color variables with ours, light and dark.

Can I use the components in Blade views?

No. They're React components, so they render inside Inertia pages (resources/js/pages), not in Blade templates. For Blade, Livewire and Flux are the Laravel-native options.

Do they work with Inertia's server-side rendering?

Yes. With Inertia SSR on, the pages and their components render on the server through Node, then hydrate. Components that need the browser do their work after hydration.

I use Laravel's Vue starter kit. What do I install?

The Vue components, with shadcn-vue's CLI. Run the Vue setup from Installation in the app's root, then add components from the Vue catalog.