lvntr/laravel-starter-kit
lvntr/laravel-starter-kit scaffolds new Laravel applications with prebuilt authentication, layouts, and common configuration, so you can skip repetitive boilerplate and start building features right away.
Treat it as a template, not a dependency. Despite the vendor/package name, a Laravel starter kit is scaffolding you copy once, not something you composer require into an existing app. Expect to install it with something along the lines of:
laravel new my-admin --using=lvntrdev/laravel-starter-kit
# or, more likely given the stack:
git clone https://github.com/lvntrdev/laravel-starter-kit my-admin
cd my-admin && composer install && npm install
cp .env.example .env && php artisan key:generate
php artisan migrate --seed && npm run dev
Read the README first, then walk the request path in this order — it tells you more than any docs:
routes/web.php (and any routes/auth.php / admin route file) — where the Inertia responses are wired.app/Http/Middleware/HandleInertiaRequests.php — the shared props (auth user, flash messages, menu) that every Vue page receives. This is the single most important file for understanding the app's contract with the frontend.resources/js/app.js (or app.ts) — Inertia + PrimeVue plugin registration, theme preset, and the page resolver glob.resources/js/Layouts/ and resources/js/Pages/ — the shell (sidebar, topbar, breadcrumbs) and a representative CRUD page.resources/css/app.css — Tailwind 4 configuration lives here as @theme / @source directives, not in a tailwind.config.js.First use case: pick a small domain model — say Project with name, status, owner — and add a full admin CRUD screen end to end. You'll touch a migration, a model, a policy, a controller returning Inertia::render('Projects/Index', [...]), and two Vue pages (Index.vue, Form.vue). Doing this once surfaces every convention the kit expects: prop shape, flash-message handling, validation error display, and how navigation entries are registered.
Before writing feature code, verify the toolchain actually boots on your machine. Laravel 13, Inertia v3, PrimeVue 4 and Tailwind 4 are all recent majors; a stale Node or PHP version is the most common reason a fresh clone fails at npm run build.
Controller → Inertia page, with typed props. Keep controllers thin and return exactly the props the page declares. A conventional index action:
public function index(Request $request)
{
return Inertia::render('Projects/Index', [
'projects' => ProjectResource::collection(
Project::query()
->when($request->string('search'), fn ($q, $s) => $q->where('name', 'like', "%{$s}%"))
->latest()
->paginate(15)
->withQueryString()
),
'filters' => $request->only('search'),
]);
}
withQueryString() matters — Inertia's client-side navigation preserves query state, and pagination links break without it.
Follow the kit's form convention rather than inventing one. Starter kits that ship PrimeVue usually pair useForm from @inertiajs/vue3 with PrimeVue inputs. The pattern worth standardizing on:
const form = useForm({ name: '', status: 'draft', owner_id: null })
const submit = () => form.post(route('projects.store'), {
onSuccess: () => form.reset(),
})
Bind :invalid="!!form.errors.name" and render form.errors.name beneath the field. Because PrimeVue components are not native inputs, v-model on them is fine but you lose browser validation — rely on server-side rules plus FormRequest classes.
Register new screens in the navigation in one place. Menu definition is typically a shared prop or a static array in the layout. Add the entry there so the sidebar, breadcrumbs and permission checks stay in sync; don't hardcode links into individual pages.
Layer authorization at three levels. Policies for row-level access ($this->authorize('update', $project)), a can map passed as a prop or exposed via shared props for UI affordances (hide the delete button), and route middleware for coarse gates. Never let the Vue v-if be your only check — the Inertia endpoint is a plain HTTP route.
Expose capabilities, not raw users. When adding role/permission support, send auth.user.permissions as an array in HandleInertiaRequests and use a small useCan() composable. Sending the full User model with relations leaks columns and bloats every response.
Reuse the table/dialog wrappers. If the kit wraps DataTable or Dialog in resources/js/Components/, extend those rather than importing PrimeVue directly in pages. That keeps a single place to change density, empty states, and confirm-delete behaviour across the panel.
Use PrimeVue's preset for theming and Tailwind for layout. PrimeVue 4 ships a design-token preset (@primevue/themes); Tailwind 4 reads design tokens from @theme in CSS. Define brand colours once in the CSS @theme block, then reference the same values in the PrimeVue preset so buttons and utility classes don't drift apart.
Deploys: npm run build must run in CI. Inertia pages are Vite entries — there's no CDN fallback, and the manifest is required at runtime in production.
composer update path to pull upstream fixes. Record the commit you scaffolded from and keep a UPSTREAM.md noting it; when you want upstream changes, diff manually. With 11 stars and zero dependents, treat upstream as a one-time gift, not a maintained dependency.package.json so a fresh npm install months later doesn't silently move you.tailwind.config.js. Custom colours, fonts and breakpoints belong in @theme inside resources/css/app.css. Copying a Tailwind 3 config from a blog post will be silently ignored. Same for @source — content paths must be declared in CSS or classes in Vue files get purged.dark class Tailwind expects versus the selector in the PrimeVue config. Align both or you get half-dark UIs.undefined render, not an error. Keep controllers and pages next to each other in review; type the props with a defineProps interface to catch this at build time.HandleInertiaRequests::share() that hits the database turns into an N+1 across the whole panel. Cache menu/permission lookups, and remember shared props also execute during partial reloads.php artisan route:list when a link 404s because the route name differs from route('...').php artisan inertia:start-ssr is optional and fragile in early-stage kits. If SSR is configured but not running, the pages still render client-side; don't spend an afternoon debugging a blank page that's just a missing manifest.Resources/js/Pages/{Domain} folder convention early so the panel doesn't collapse into a flat Pages/ directory at fifty screens.How can I help you explore Laravel packages today?