tallstackui/starter-kit
A Laravel starter kit for the TALL stack, preconfigured with TallStackUI components, authentication, layouts, and common UI patterns. It gives you a ready foundation to scaffold new applications quickly without rebuilding the basics.
Because this is a starter kit rather than a runtime library, "getting started" means scaffolding a project and then immediately learning the layout of the generated code — not wiring up a dependency you'll bump over time.
Scaffold a project
laravel new my-app --using=tallstackui/starter-kit
# or, without the installer:
composer create-project tallstackui/starter-kit my-app
cd my-app
composer install
npm install
cp .env.example .env && php artisan key:generate
php artisan migrate
npm run dev # Vite; TallStackUI relies on the Tailwind build
php artisan serve
Register a user through /register first. That single flow touches most of what you'll customize (Livewire component, Blade view, layout, form components, validation) and is the fastest way to confirm the Tailwind + Alpine + Livewire pipeline is actually working before you change anything.
Where to look first, in order
routes/web.php — the shape of the app. Auth routes, the auth middleware group, and the dashboard/profile entries are all here.resources/views/components/layouts/ — the shell (navbar/sidebar, dark-mode toggle, slot). Almost every page custom you make reuses this.app/Livewire/Auth/ and app/Livewire/Profile/ (names may differ slightly) — the auth and account-management components. These are the reference implementations for your future Livewire pages.resources/views/livewire/ — the matching Blade views, which is where you'll see TallStackUI component usage (<x-input>, <x-button>, <x-modal>, <x-card>, <x-form>, toasts, etc.).config/tallstackui.php — theming, component prefix, and defaults. Publish it if it isn't already (php artisan vendor:publish --tag=tallstackui.config).tailwind.config.js / resources/css/app.css — content globs and the TallStackUI preset/plugin.First real use case: replace the dashboard with your own page. Add a route, generate a Livewire component (php artisan make:livewire Dashboard), point its view at the starter kit layout with <x-layouts.app>, and rebuild one of the auth forms using TallStackUI components so you learn the prop API (label, error, wire:model.live) on a page you own.
Treat the generated code as your codebase, not as a vendored package. The correct mental model: every file in app/Livewire and resources/views is a template you are expected to edit in place. Do not try to "override" starter kit behavior from a separate package — there is no extension pipeline for it. Fork early, commit the pristine scaffold as your first commit so you can diff against it later.
Compose new pages from the existing layout + Livewire. The dominant pattern is: route → full-page Livewire component → view that extends the starter kit layout and uses TallStackUI primitives.
// routes/web.php
Route::middleware('auth')->group(function () {
Route::get('/reports', ReportIndex::class)->name('reports.index');
});
{{-- resources/views/livewire/report-index.blade.php --}}
<div>
<x-card>
<x-form wire:submit="save">
<x-input label="Name" wire:model="name" />
<x-button type="submit" label="Save" />
</x-form>
</x-card>
</div>
The wrapper <div> is required for Livewire full-page components — a common first stumble.
Copy the auth components as your CRUD template. The login/register components already demonstrate the house style: form requests or inline rules(), wire:model binding, TallStackUI error display, $this->redirect(...) on success, flash/toast on failure. Cloning one of these and renaming it is faster and more consistent than starting from a blank Livewire component.
Keep authorization in one place. The starter kit ships with basic authenticated-user assumptions. As soon as you add roles/teams, centralize it with Gates/Policies rather than sprinkling if (auth()->user()->isAdmin()) across Livewire components — Livewire's public properties are serialized to the client, so any authorization logic must live server-side in mount(), authorize(), or a policy check, never in the Blade or a public property.
Theming via config, not component surgery. Adjust colors, the dark-mode behavior, and component defaults in config/tallstackui.php and the Tailwind config rather than editing vendor components. If you need a genuinely different button, publish the component to resources/views/vendor/tallstackui/ and edit there — the vendor publish workflow is the supported extension point.
Add pages as full-page Livewire components, guarded by middleware. Prefer Route::get(..., Component::class) over the older Route::view(...) + controller, since it matches the rest of the kit and gives you reactive pages for free.
Profile/account updates follow a two-step pattern in the starter kit: separate components for profile info and password. Mirror that split for anything involving sensitive state (email changes, 2FA) rather than one giant settings component — it keeps validation rules isolated and makes the "confirm password" middleware easier to apply.
Wire up email verification and password reset through Laravel's existing contracts. The starter kit implements the UI; you still need MustVerifyEmail on the User model and a working mailer (Mailpit/log driver locally) before those flows work end-to-end.
composer update will update Laravel and Livewire, but you will never receive starter kit fixes. Pin Laravel/Livewire/TallStackUI versions in composer.json deliberately and re-scaffold fresh when a new kit release matters.app/Http/Kernel.php. Middleware registration lives in bootstrap/app.php via ->withMiddleware(...). Older Breeze/Jetstream tutorials will send you to a file that doesn't exist. Same for RouteServiceProvider (gone) and config/app.php providers (auto-discovered).wire:model (v3 is deferred by default; .live is opt-in) and the #[Layout] / #[Title] attributes. Mixing v2 idioms into a v3 app produces silent "not updating" bugs rather than errors.isAdmin flag, or a full Eloquent model with sensitive fields in a public property. Use mount() locals and re-derive ownership inside actions. This is the most common security mistake when extending a starter kit.wire:key. Rendering components in loops without wire:key causes state bleed and mysterious form resets. TallStackUI modals/dropdowns are Alpine-driven and are especially sensitive to this — always key the parent loop item.content array, or the package's own views not being included. Check tailwind.config.js before debugging the component.npm install && npm run dev (or npm run build) before assuming a page is broken. A blank Alpine page is usually an un-built Vite bundle.<html> and likely persists in localStorage. If you set a dark background on body it will survive the toggle; if you set it on a wrapper component the toggle looks broken. Follow the kit's convention, don't invent a parallel one.php artisan optimize:clear (or view:clear + route:clear + config:clear) resolves a surprising number of "my change didn't take" reports after editing Blade components or config.$this->authorize() inside Livewire actions, not just mount(). mount() runs once; actions run on every request. Re-verify ownership in update()/delete() methods even if mount() already loaded the record — a Livewire component's public IDs can be reassigned from the client.config/tallstackui.php or a vendor view, you own it and won't get upstream changes. Publish sparingly and note it in your README.starter-kit name collision. Some editor/tooling integrations and older docs refer to Jetstream or Breeze starter kits; the TallStackUI one is Livewire-native and has no Fortify dependency by default, so don't apply Fortify-specific guidance (e.g. config/fortify.php, action classes) to it without first confirming the package is even installed.How can I help you explore Laravel packages today?