PHPackages                             shipbytes/laravel-ui-kit - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. shipbytes/laravel-ui-kit

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

shipbytes/laravel-ui-kit
========================

Admin panel + auth UI kit for Laravel with Livewire 3, Volt, and Tailwind. Modular installers for optional features.

v0.1.0(3mo ago)06MITBladePHP ^8.1CI passing

Since Apr 25Pushed 3mo agoCompare

[ Source](https://github.com/shipbytes/laravel-ui-kit)[ Packagist](https://packagist.org/packages/shipbytes/laravel-ui-kit)[ Docs](https://github.com/shipbytes/laravel-ui-kit)[ RSS](/packages/shipbytes-laravel-ui-kit/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependencies (11)Versions (2)Used By (0)

Laravel UI Kit
==============

[](#laravel-ui-kit)

Admin panel + auth UI scaffolding for Laravel 10/11/12/13 with Livewire 3, Volt, Fortify, and Tailwind 3.

Core + 9 optional modules, installed interactively via `php artisan ui-kit:install`. CI covers PHP 8.1–8.4 × Laravel 10/11/12. See [CHANGELOG.md](CHANGELOG.md) for release notes.

What you get
------------

[](#what-you-get)

### Always installed (core)

[](#always-installed-core)

- **Auth pages** — login, register, forgot/reset password, email verification, confirm password (Livewire Volt + Fortify)
- **Admin shell** — collapsible sidebar, mobile bottom nav, nav-config-driven from `config/admin.php`
- **Dashboard stub + Users CRUD**
- **Tailwind preset** — fonts (Inter/Poppins/Montserrat), brand palette, dark-mode class strategy
- **Alpine stores** — sidebar collapse (localStorage-persisted), theme toggle

### Optional modules

[](#optional-modules)

SlugWhat it addsComposer deps`admin-middleware`Spatie Permissions wiring (falls back to `is_admin` boolean if skipped)`spatie/laravel-permission:^6.0``support-tickets`Admin ticket queue + replies (Mailables left to you)—`changelog`Admin-authored changelog with public feed`mews/purifier:^3.4``contacts`Contact-form submission inbox—`analytics`UTM tracking, GA4, PostHog (pick any combination)—`profile`Self-service name/email/password/avatar + 2FA toggle— (optional: `intervention/image`)`impersonation`Login-as-user with exit ribbon + button partial`lab404/laravel-impersonate:^1.7``activity-log`Spatie activity log + filterable admin viewer`spatie/laravel-activitylog:^4.8``dark-mode``` component + no-flash inline snippet—Every module prints a numbered **Next steps** checklist after `ui-kit:install-module` — we don't auto-patch your route files or `config/admin.php`.

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10, 11, 12, or 13
- Livewire 3 + Volt 1.x
- Node 18+ (for Vite / Tailwind build)

> ⚠️ **Laravel 10 is past its security window.** The package supports it for compatibility, but new projects should target L11+.

Before you install — fresh vs. existing app
-------------------------------------------

[](#before-you-install--fresh-vs-existing-app)

The kit is designed for **fresh Laravel installs** (no auth scaffolding yet). Running it on top of Breeze, Jetstream, or a custom auth setup will collide.

The installer does a **preflight check** for you — it reads your `composer.lock` for `laravel/breeze` / `laravel/jetstream` and scans for colliding file paths (`routes/auth.php`, `app/Livewire/Forms/LoginForm.php`, `resources/views/livewire/pages/auth/*`). Behaviour:

- **Jetstream detected** → aborts. Pass `--force` to override (not recommended).
- **Breeze detected** (or stray auth files) → warns, lists the collisions, and prompts you to confirm.
- Running `--no-interaction` with collisions present → aborts unless `--force` is set. Keeps CI safe.

### ✅ Do install on

[](#-do-install-on)

- **A fresh `laravel new` project** with no auth starter. Zero conflicts, ~2 minutes to a working admin + auth UI.
- **An existing app that has no auth UI yet** (e.g. an API-only app you're now adding an admin panel to). You'll still want to uninstall any partial auth views from `resources/views/auth/` first.

### ⚠️ Avoid installing on top of

[](#️-avoid-installing-on-top-of)

- **Breeze (any stack)** — collides on `routes/auth.php`, `app/Livewire/Forms/LoginForm.php` (Breeze Livewire), and `resources/views/livewire/pages/auth/*`. Without `--force` Laravel silently skips them, leaving you with Breeze's code running under this kit's layouts — usually broken. With `--force`, Breeze is overwritten and may leave orphaned files behind.
- **Jetstream** — heavy footprint (teams, API tokens, Sanctum-based auth) that this kit doesn't understand. Do not combine.
- **An app with customized Fortify views/actions** — your customizations will either be skipped or overwritten depending on `--force`.

If you *must* use the kit on top of an existing auth setup, remove the starter first:

```
# Breeze — no official uninstaller, remove by hand:
composer remove laravel/breeze
rm -rf app/Http/Controllers/Auth resources/views/auth routes/auth.php
rm -f app/Livewire/Forms/LoginForm.php app/Livewire/Actions/Logout.php
rm -rf resources/views/livewire/pages/auth resources/views/components/{input-error,input-label,primary-button,text-input}.blade.php

# Jetstream — no uninstaller, migration is significant. Start from a fresh app.
```

Then run the kit installer. Review the generated files before committing — merge anything you wanted to keep from your old setup by hand.

### What the installer publishes (so you can eyeball conflicts)

[](#what-the-installer-publishes-so-you-can-eyeball-conflicts)

DestinationFrom`config/ui-kit.php`, `config/admin.php`kit-specific, safe`resources/views/layouts/*`, `components/auth-session-status.blade.php`**collides with Breeze**`resources/views/livewire/pages/auth/*`**collides with Breeze Livewire**`resources/views/livewire/admin/*`kit-specific, safe`app/Livewire/Admin/*`, `app/Livewire/Forms/LoginForm.php`**`LoginForm` collides with Breeze Livewire**`routes/auth.php`**collides with Breeze**`routes/admin.php`kit-specific, safe`resources/js/ui-kit.js`, `resources/css/ui-kit.css`kit-specific, safe`database/migrations/..._add_is_admin_to_users_table.php`kit-specific, timestamped, safeInstall
-------

[](#install)

```
composer require shipbytes/laravel-ui-kit
php artisan ui-kit:install
```

The installer walks you through an interactive module picker. Run `php artisan ui-kit:install --modules=admin-middleware,profile` to skip the prompt.

**Installing before a Packagist release (or straight from GitHub / a local path)**Until a version is tagged and submitted to Packagist, or if you're hacking on the kit locally, point Composer at the source directly.

**From GitHub (VCS repository)** — good for tracking `main`:

```
composer config repositories.laravel-ui-kit vcs https://github.com/shipbytes/laravel-ui-kit
composer config minimum-stability dev
composer config prefer-stable true
composer require "shipbytes/laravel-ui-kit:dev-main"
```

**From a local checkout (path repository)** — good for contributors; symlinks the source into `vendor/` so edits are live:

```
composer config repositories.laravel-ui-kit path /absolute/path/to/laravel-ui-kit
composer require "shipbytes/laravel-ui-kit:*"
```

If symlinking causes trouble (e.g. WSL file-permission quirks), disable it:

```
composer config repositories.laravel-ui-kit '{"type":"path","url":"/absolute/path/to/laravel-ui-kit","options":{"symlink":false}}'
composer update shipbytes/laravel-ui-kit
```

### Finish wiring

[](#finish-wiring)

The installer does almost everything — publishes assets/configs/migrations, patches `config/fortify.php` and `config/admin.php` (middleware + nav), appends module routes, runs `vendor:publish` for every dependent package, runs one `php artisan migrate`, seeds the admin role, runs `storage:link`, installs npm packages where required, and generates `app/Models/Concerns/UiKitUser.php` based on which modules you picked.

That leaves a small irreducible checklist you do **once**:

1. **Add the kit's User trait** (only if you picked `admin-middleware` or `impersonation`): ```
    // app/Models/User.php
    use App\Models\Concerns\UiKitUser;

    class User extends Authenticatable
    {
        use UiKitUser;   //  **What the installer handled for you**
>
> - Published every kit + dependency config (Fortify, Spatie Permission, mews/purifier, lab404/impersonate, Spatie Activitylog).
> - Patched `config/fortify.php` (`views=false`), `config/admin.php` (middleware swap + nav entries between `/* ui-kit:nav-* */` markers), and `routes/admin.php` (module routes between `/* ui-kit:admin-routes-* */` markers).
> - Auto-loads `routes/auth.php`, `routes/admin.php`, and `routes/ui-kit-user.php` from the service provider — no `bootstrap/app.php` edit required.
> - Pushed the UTM-capture middleware into the `web` group at runtime (when `analytics:utm` is installed), so you don't have to register it manually.
> - Reads `GOOGLE_ANALYTICS_ID` / `POSTHOG_PUBLIC_KEY` / `POSTHOG_HOST` directly from `.env` into `services.google.*` and `services.posthog.*` at boot — no `config/services.php` edit needed.
> - Generated `app/Models/Concerns/UiKitUser.php` bundling whatever traits and methods your installed modules require.
> - All patches are **idempotent** — re-running `ui-kit:install` (or installing more modules later) won't duplicate nav entries or routes.
> - On Windows cmd / Laragon / some WSL emulators, the picker uses a plain numbered-list prompt instead of Laravel Prompts' alt-screen rendering. Override with `UI_KIT_PROMPTS_FALLBACK=0` (force fancy) or `=1` (force plain).

Configuration
-------------

[](#configuration)

### Brand

[](#brand)

```
// config/ui-kit.php
'brand' => [
    'name' => env('UI_KIT_BRAND_NAME', config('app.name')),
    'logo' => env('UI_KIT_BRAND_LOGO', '/images/logo.png'),
    'home_route' => env('UI_KIT_HOME_ROUTE', 'home'),
],
```

Drop your logo PNG/SVG at `public/images/logo.png` (or override `UI_KIT_BRAND_LOGO` to point anywhere else). `home_route` is the route name used by the "back to site" link in the admin shell.

### Sidebar navigation

[](#sidebar-navigation)

```
// config/admin.php
'nav' => [
    ['label' => 'Dashboard', 'route' => 'admin.dashboard', 'icon' => 'grid'],
    ['label' => 'Users', 'route' => 'admin.users.index', 'icon' => 'users'],
    ['section' => 'Support'],
    ['label' => 'Tickets', 'route' => 'admin.tickets.index', 'icon' => 'ticket', 'badge' => 'open_tickets'],
],
```

Each installed module's `Next steps` checklist tells you the exact nav entry to paste.

### Sidebar badges

[](#sidebar-badges)

Bind your own resolver so sidebar counters (e.g. "open tickets: 12") reflect your data:

```
// In a service provider
$this->app->bind(
    \Shipbytes\UiKit\Contracts\SidebarBadgeResolver::class,
    \App\Support\AdminBadgeResolver::class,
);
```

The resolver returns `['open_tickets' => 12, 'unread_contacts' => 3, ...]` — keys match the `badge` field on nav items.

Environment &amp; credentials
-----------------------------

[](#environment--credentials)

This section is a single place to see **every `.env` key** the kit can read, with links to where to generate the values. Only the **Mail** block is required for a production-ready install; everything else depends on which modules you enable.

### `.env` reference

[](#env-reference)

```
# --- Branding (all optional; sensible defaults if unset) -----------------
UI_KIT_BRAND_NAME="Acme"
UI_KIT_BRAND_LOGO="/images/logo.png"
UI_KIT_HOME_ROUTE="home"

# --- Mail (required for password reset, email verification) --------------
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=postmaster@mg.example.com
MAIL_PASSWORD=your-smtp-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="noreply@example.com"
MAIL_FROM_NAME="${APP_NAME}"

# --- Analytics module: GA4 (only if you installed analytics+ga4) ---------
GOOGLE_ANALYTICS_ID=G-XXXXXXXXXX

# --- Analytics module: PostHog (only if you installed analytics+posthog) -
POSTHOG_PUBLIC_KEY=phc_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
POSTHOG_HOST=https://us.i.posthog.com   # or https://eu.i.posthog.com
```

### Mail (for auth emails)

[](#mail-for-auth-emails)

Fortify sends password-reset and email-verification messages through Laravel's mailer. Out of the box, `MAIL_MAILER=log` works for local dev (mail goes to `storage/logs/laravel.log`). For production, pick any supported driver — Mailgun, Postmark, SES, Resend, or SMTP. See the [Laravel mail docs](https://laravel.com/docs/mail) for driver-specific setup.

If you don't configure mail, the UI will appear to work but users will never receive verification or reset emails.

### GA4 (Google Analytics 4)

[](#ga4-google-analytics-4)

**1. Generate a Measurement ID.**

1. Go to [analytics.google.com](https://analytics.google.com).
2. Admin (gear icon, bottom-left) → **Create** → **Property** (or pick an existing one).
3. Inside the property: **Data streams** → **Add stream** → **Web** → enter your site URL.
4. Copy the **Measurement ID**. It looks like `G-XXXXXXXXXX`.

**2. Paste it into `.env`.**

```
GOOGLE_ANALYTICS_ID=G-XXXXXXXXXX
```

**3. Register the config key** in `config/services.php` (add this once):

```
'google' => [
    'analytics_id' => env('GOOGLE_ANALYTICS_ID'),
],
```

**4. Include the loader** in your app layout, just before ``:

```
@include('partials.ga4')
```

**5. Consent gating.** The loader only fires once a `cookie_consent=accepted` cookie is present. Set that cookie from your consent banner (or manually in dev via DevTools) — otherwise the GA4 script never runs. This is intentional so you're GDPR/CCPA-ready.

Verify it's working: open your site, accept the cookie banner, and watch **Realtime** in the GA4 UI. You should see yourself within ~30 seconds.

### PostHog

[](#posthog)

**1. Grab your Project API Key.**

1. Sign up / log in at [posthog.com](https://posthog.com) (or run self-hosted).
2. Pick the project you want to track into.
3. **Settings** (gear icon, bottom-left) → **Project** → **General** → copy **Project API Key**. It starts with `phc_…`.
4. Note your **host**: `https://us.i.posthog.com` for PostHog Cloud US, `https://eu.i.posthog.com` for EU, or your own URL for self-hosted.

**2. Paste into `.env`.**

```
POSTHOG_PUBLIC_KEY=phc_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
POSTHOG_HOST=https://us.i.posthog.com
```

**3. Register config keys** in `config/services.php`:

```
'posthog' => [
    'public_key' => env('POSTHOG_PUBLIC_KEY'),
    'host'       => env('POSTHOG_HOST', 'https://us.i.posthog.com'),
],
```

**4. Include the loader** in your app layout, just before ``:

```
@include('partials.posthog')
```

**5. Install the JS SDK + bridge** so server-side Livewire events can capture PostHog events:

```
npm install posthog-js
```

```
// resources/js/app.js
import './posthog-bridge';
```

**6. Capture events from Livewire:**

```
$this->dispatch('posthog-capture', event: 'ticket_replied', properties: [
    'ticket_id' => $ticket->id,
]);
```

**7. Consent gating.** Same as GA4 — the loader waits for `cookie_consent=accepted`. Verify in the PostHog **Live events** tab.

> ⚠️ Only use your **public** project key (`phc_…`). The personal / private API key should never land in frontend code.

### UTM tracking (analytics module, UTM provider)

[](#utm-tracking-analytics-module-utm-provider)

No external service or key needed. Once you register the middleware, anyone who hits your site with `?utm_source=…&utm_medium=…&utm_campaign=…` on the URL gets the values stashed in their session (and attached to the User model on signup). The UTM Link Builder page (`/admin/analytics/utm`) generates tagged URLs for your campaigns.

Installing modules later
------------------------

[](#installing-modules-later)

```
php artisan ui-kit:install-module support-tickets
php artisan ui-kit:install-module analytics --providers=utm,posthog
php artisan ui-kit:list-modules
```

Module deep-dives
-----------------

[](#module-deep-dives)

### `admin-middleware`

[](#admin-middleware)

Ships `EnsureUserIsAdmin` (Spatie role check) + `AdminRoleSeeder`. The installer publishes Spatie's config/migrations, runs `migrate` and `db:seed --class=AdminRoleSeeder`, swaps the middleware in `config/admin.php` from the fallback to `App\Http\Middleware\EnsureUserIsAdmin::class`, and generates `App\Models\Concerns\UiKitUser` bundling Spatie's `HasRoles` trait. You add `use UiKitUser;` to your User model and `assignRole('admin')` to one user.

### `support-tickets`

[](#support-tickets)

Admin-only queue (public form is yours to build). Search by name/email, filter by status/priority, inline replies. Mailables are intentionally omitted so you plug in your own notification flow.

### `changelog`

[](#changelog)

Admin CRUD + public feed helper. HTML sanitization via `mews/purifier`. Each entry has a status (`published`/`draft`) and a category.

### `contacts`

[](#contacts)

Inbox for a public contact form that writes to `contact_submissions`. When the `support-tickets` module is also installed, a **Copy to Ticket** button auto-appears — no config needed.

### `analytics`

[](#analytics)

Three providers — pick any combination at install time. See [Environment &amp; credentials](#environment--credentials) above for the full GA4 / PostHog setup walkthroughs.

- **UTM** — middleware captures `?utm_*` → session, User model columns, and a Livewire-powered link builder at `/admin/analytics/utm`. No external service required.
- **GA4** — consent-gated `@include('partials.ga4')` loader. Needs `GOOGLE_ANALYTICS_ID`.
- **PostHog** — consent-gated loader + Livewire→PostHog JS bridge. Needs `POSTHOG_PUBLIC_KEY` (+ optional `POSTHOG_HOST`).

Both GA4 and PostHog loaders gate on `cookie_consent=accepted`. Set that cookie from your consent banner (or your tests).

### `profile`

[](#profile)

Four Livewire/Volt cards under a single `ProfilePage`: update info + avatar, update password, 2FA (Fortify, auto-hidden if not installed), delete account. Ships `x-modal` and `x-action-message` components. Resizes avatars to 200×200 if `intervention/image` is installed, otherwise stores the raw upload. Don't forget `php artisan storage:link` so `/storage/avatars/...` is publicly reachable.

### `impersonation`

[](#impersonation)

Two Blade partials (`impersonation-banner`, `impersonation-button`) over `lab404/laravel-impersonate`. The package auto-registers routes; you just `@include` the banner in your layout and the button in the user detail view. Requires `canImpersonate()` + `canBeImpersonated()` methods on your User model.

### `activity-log`

[](#activity-log)

Paginated admin viewer over `spatie/laravel-activitylog`'s `activity_log` table. Filters: log stream, causer email, date range. Add the `LogsActivity` trait on your models per [Spatie's README](https://spatie.be/docs/laravel-activitylog).

### `dark-mode`

[](#dark-mode)

Alpine `$store.theme` ships in core/`ui-kit.js`. Drop `` anywhere and inline the no-flash snippet before ``. Every core view and every shipped module has `dark:` variants already.

Laravel version caveats
-----------------------

[](#laravel-version-caveats)

- **L10:** Volt routes require explicit `Volt::mount()`. The service provider calls it automatically when it detects published Volt pages. EOL'd security support — bump to L11+ when you can.
- **L11:** middleware registration moved to `bootstrap/app.php`. Post-install notes call out the relevant `bootstrap/app.php` vs `Http/Kernel.php` snippet so you know where to drop in the new middleware.
- **L12:** current LTS-ish target — the default for new projects using this kit.
- **L13:** newly released (per PHP/Fortify/Spatie peer-dep readiness). CI runs 10/11/12 until the ecosystem catches up; bump `composer.json` locally if you want to try it early.

Troubleshooting
---------------

[](#troubleshooting)

- **`/login` returns 500 with "Vite manifest not found"** — run `npm run dev` or `npm run build`. Vite must emit a manifest before Blade's `@vite` directive can resolve it.
- **Password reset / verification emails never arrive** — check `MAIL_*` in `.env`. In local dev, set `MAIL_MAILER=log` and tail `storage/logs/laravel.log`.
- **GA4 / PostHog not firing** — open DevTools → Application → Cookies and confirm `cookie_consent=accepted` is set. Both loaders are consent-gated by design.
- **Sidebar badges show 0 / blank** — bind your own `SidebarBadgeResolver`; the default returns an empty array.
- **"Unauthorized" on `/admin`** — either the default fallback middleware is rejecting you (it requires `$user->is_admin` to be truthy) or you installed `admin-middleware` and haven't assigned the `admin` role yet.

Testing the package
-------------------

[](#testing-the-package)

```
composer install
vendor/bin/phpunit
```

Tests run against Orchestra Testbench. CI (`.github/workflows/tests.yml`) matrixes PHP 8.1–8.4 × Laravel 10/11/12.

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance82

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

90d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/417bd3ee43af064db51d8ba5dfe03919bce3f0cff848adc0b0d2faa6279cac63?d=identicon)[shipbytes](/maintainers/shipbytes)

---

Top Contributors

[![shipbytes](https://avatars.githubusercontent.com/u/24540330?v=4)](https://github.com/shipbytes "shipbytes (7 commits)")

---

Tags

laravelauthlivewiretailwindvoltadminui-kit

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/shipbytes-laravel-ui-kit/health.svg)

```
[![Health](https://phpackages.com/badges/shipbytes-laravel-ui-kit/health.svg)](https://phpackages.com/packages/shipbytes-laravel-ui-kit)
```

###  Alternatives

[livewire/flux

The official UI component library for Livewire.

9577.8M138](/packages/livewire-flux)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M133](/packages/roots-acorn)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M136](/packages/laravel-pulse)[tallstackui/tallstackui

TallStackUI is a powerful suite of Blade components that elevate your workflow of Livewire applications.

728176.2k14](/packages/tallstackui-tallstackui)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[laravel/boost

Laravel Boost accelerates AI-assisted development by providing the essential context and structure that AI needs to generate high-quality, Laravel-specific code.

3.5k21.5M673](/packages/laravel-boost)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
