Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Wirekit Laravel Package

pushery/wirekit

A free, open-source UI component library for Laravel Livewire, built on Tailwind CSS v4 and Alpine.js. Forms, navigation, overlays, layout, marketing and data display components — themeable, accessible and dark-mode ready.

View on GitHub
Deep Wiki
Context7

Getting Started

WireKit is a Blade component library, not a Livewire component generator — you consume <x-wirekit::*> tags directly inside your own Livewire views. There is nothing to scaffold and no build step beyond Tailwind.

1. Install and wire the directives into your layout.

composer require pushery/wirekit
php artisan wirekit:install

The installer publishes config and writes .wirekit-schema.json for editor autocomplete. If it can't find a layout it will print a hint for the Livewire 4 path (resources/views/components/layouts/app.blade.php) — the 2.8.1 patch fixed a wrong path in that hint, so check it matches your app before following it.

2. Add the two directives to your layout.

<head>
    @wirekitStyles
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
    {{ $slot }}
    @wirekitScripts
</body>

3. Register the Blade source path in resources/css/app.css. This is the step people skip and it is the one that fails silently:

@import 'tailwindcss';
@source '../../vendor/pushery/wirekit/resources/views/**/*.blade.php';

Without it Tailwind never sees the classes inside the package views, so the components render unstyled with no error at all.

Where to look first. Do not start from the README — start from the manifest already installed in your project:

php artisan wirekit:list                        # everything, grouped by category
php artisan wirekit:show input                  # props, slots, sub-components, docs URL
php artisan wirekit:icons                       # icon aliases per preset
php artisan wirekit:export-json --pretty        # machine-readable catalog

wirekit:show is authoritative for your installed version; the docs site can drift ahead of it. In 2.9.0 the shipped Cursor rules had in fact drifted from the real API (layout primitives take gap, not space; the button takes intent), which is a good reason to trust the CLI over prose.

First use case: a settings form in an existing Livewire component. This is the highest-value, lowest-risk entry point — form controls are self-contained and don't dictate your page shell.

<form wire:submit="save">
    <x-wirekit::input label="Email" type="email" name="email" wire:model="email" />
    <x-wirekit::select
        label="Role"
        name="role"
        :options="['admin' => 'Admin', 'user' => 'User']"
        wire:model="role"
    />
    <x-wirekit::textarea label="Bio" name="bio" wire:model="bio" hideLabel />

    <x-wirekit::button type="submit">Save</x-wirekit::button>
    <x-wirekit::button intent="danger" wire:click="delete">Delete</x-wirekit::button>
</form>

You get accessible labelling, dark mode, and focus states for free, and you never hand-write a Tailwind class chain.

Implementation Patterns

Composition over configuration. The library leans on sub-components rather than props. A card is card + card.body; an app dashboard is a shell composed of app-shell, header, main, footer, sidebar. In 2.9.0 the card component will log a dev-mode warning if you drop content straight into it without a card.body — treat that warning as a composition error, not noise.

Pick one layout shell and commit. navbar and app-shell are alternatives, not layers. Mixing them produces double headers and competing sticky behaviour. For an authenticated dashboard use app-shell; for a marketing page use navbar + hero / feature-grid / cta.

Form pattern. Bind with wire:model on the component's real <input>, not a wrapper, and let label / hint / error props carry validation messaging. For compact toolbar or filter-bar fields use hideLabel — it keeps the <label> in the DOM (preserving the accessible name) but renders it visually hidden. Reach for hideLabel instead of omitting label, which drops the accessible name entirely.

Overlays are Alpine-driven, so let them own their state. Put a modal / drawer / dropdown in the Blade, gate it with its own trigger, and drive server behaviour from wire:click inside it. Don't try to open a modal from a Livewire property — the JS state isn't synced with PHP.

Non-Livewire form actions. dropdown.item honors a caller type; a no-href item defaults to type="button", but type="submit" lets it drive a wrapping <form> — the canonical non-Livewire CSRF logout.

Discovery-first workflow. Before authoring any non-trivial block, run wirekit:list for the category and wirekit:show <component> for exact props. For AI-assisted authoring, 2.9.0 adds php artisan wirekit:mcp-serve (local, read-only, stdio, version-matched) plus wirekit:boost-skills to publish .boost/wirekit.json. Both are generated from your installed package, so they cannot drift — re-run after every upgrade.

Theming at the token layer. Customize with --color-wk-* variables rather than class overrides:

@layer base {
    :root {
        --color-wk-accent: var(--color-blue-600);
    }
}

Because components read tokens everywhere, a single variable change reskins the whole app consistently, dark mode included — which is the entire reason not to reach for class="..." overrides.

Optimistic UI is opt-in and free when unused. Add optimistic="yourMethod" to a supported component and load wirekit-optimistic.js. Components that don't use it render byte-identically and pay nothing, so you can adopt it on one hot path (a toggle, a like button) without a global decision.

Gotchas and Tips

  • Styled-but-broken is almost always the @source line. If components look unstyled, check that directive, that the path is relative to app.css, and that the glob ends in **/*.blade.php. The docs ship a "Styles not applying?" checklist — start there, not with the CSS cascade.
  • Version floor is aggressive. PHP 8.4+, Laravel 12+/13+, Livewire 4+, Tailwind v4. This is not droppable into a Livewire 3 / Laravel 11 / Tailwind 3 app, and there is no shim layer. Confirm all four before proposing it.
  • License metadata disagrees with itself. Packagist reports NOASSERTION while the README and badge say MIT. Before adopting, open LICENSE in the vendor directory and confirm — it takes a minute and matters for procurement.
  • Adoption risk is real. 22 stars, zero dependents, first release late 2026. Treat it as a fast-moving solo/small-team project: pin the constraint in composer.json ("pushery/wirekit": "^2.9"), commit the lockfile, and read the changelog before bumping. Budget for the possibility of forking the Blade views if the project stalls — which the publish mechanism already makes feasible.
  • Misspelled props now warn in dev only. As of 2.9.0, form controls plus button, badge, alert, stat, callout, progress, and tooltip log a "did you mean" hint. Silent in production, so watch storage/logs/laravel.log during development — a silently ignored variant= where intent= was meant will otherwise cost you an hour.
  • ApexCharts is not MIT. Chart.js adapter is MIT; ApexCharts is free only under $2M USD revenue and commercial above. WireKit ships adapter glue only. Default to 'charts' => ['library' => 'chartjs'] in config/wirekit.php and require a deliberate decision before shipping ApexCharts to production. Per-instance override (library="apexcharts") makes it easy to introduce accidentally during a copy-paste.
  • Icons need a preset. Aliases resolve per-preset; settings, gear, dashboard, billing, and credit-card gained base-preset glyphs in 2.9.0, but a new alias you invent won't resolve until you register it. Verify with php artisan wirekit:icons before debugging a blank icon.
  • Extension points, in ascending invasiveness: theme tokens (--color-wk-*) → config (fonts, charts, icon presets) → publishing Blade views and editing them. Stay at the token level as long as you can; published views become your maintenance burden on every upgrade.
  • Localization and browser baseline. Translations follow the standard Laravel lang/vendor publishing path. The browser baseline is pinned to Tailwind v4 (Chrome/Edge 111, Safari 16.4, Firefox 128) with no polyfills — fine for a modern SaaS dashboard, a genuine problem if you serve a kiosk, an embedded webview, or a long-tail enterprise estate.
  • @wirekitScripts belongs at the end of <body>. Alpine needs to be present before component scripts initialize; putting it in <head> produces overlays that never open.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core