Skip to content

Laravel Starter Kits Ship Vite+: What Got Deleted and Why

Laravel Starter Kits Ship Vite+: What Got Deleted and Why

I deleted my ESLint config in April and wrote a whole post gloating about it. Turns out I was just early. As of this week, every official Laravel starter kit ships with Vite+, and the ESLint and Prettier setup I spent years copy-pasting between projects is gone from the React, Vue, Svelte, and Livewire kits entirely. Paul Redmond covered the change at Laravel News, and the diff landed in laravel/maestro#60, which pins vite-plus at 0.3.0 and synced out to all four kit repositories the same day.

Short version for the impatient: four npm scripts became two, three config files became zero, and about a dozen devDependencies vanished. If you want to know whether that’s actually good news or just churn, read on. I have opinions on both sides.

What Vite+ actually is

Vite+ is VoidZero’s unified toolchain, released in beta on July 2, 2026. It’s a single CLI called vp that wraps Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task, and it manages your runtime and package manager on top of that. The pitch is one tool, one config, one lockfile-adjacent headache instead of seven separate ones.

I was skeptical when it launched. I’m old enough to remember when “one tool to rule them all” meant Grunt, and then it meant Gulp, and then Webpack ate everything for eight years. The difference this time is that the pieces under the hood aren’t new projects. Vite already won the bundler war for app development. Oxlint and Oxfmt are the Rust rewrites of the ESLint and Prettier jobs, and they’ve been stable enough that I moved my own projects to the Oxc toolchain months ago. Vite+ is less a new tool and more a staple through tools you were probably already using.

The Vite+ documentation is short, which I mean as a compliment. There’s not much to configure because most of it has defaults you won’t fight.

What the starter kits looked like before

Here’s the frontend script block every Inertia starter kit carried until this week. If you’ve generated a Laravel app in the last two years, this will look familiar:

"scripts": {
    "build": "vite build",
    "build:ssr": "vite build && vite build --ssr",
    "dev": "vite",
    "lint": "eslint . --fix",
    "lint:check": "eslint .",
    "format": "prettier --write resources/",
    "format:check": "prettier --check resources/"
}

Behind those scripts sat eslint.config.js, .prettierrc, and .prettierignore, plus the dependency pile that made them work: eslint, typescript-eslint, prettier, prettier-plugin-tailwindcss, framework-specific ESLint plugins for React, Vue, and Svelte, an imports plugin, and globals. The React kit alone carried 129 lines of ESLint config. I know because I’ve scrolled past all 129 of them looking for the one rule I wanted to change, more times than I’d like to admit.

What they look like now

The new script block:

"scripts": {
    "build": "vp build",
    "build:ssr": "vp build && vp build --ssr",
    "dev": "vp dev",
    "check": "vp check",
    "check:fix": "vp check --fix",
    "types:check": "tsc --noEmit"
}

vp check formats with Oxfmt, lints with Oxlint, and type checks in a single pass. The composer ci:check command follows along, running npm run check where it used to run the lint check and format check back to back. Two CI steps became one, and the one is faster than either of the old two because the linter isn’t written in JavaScript anymore.

The rules didn’t disappear, they moved. Lint and format config now lives in vite.config.ts under lint and fmt keys:

import { defineConfig, lazyPlugins } from 'vite-plus';

export default defineConfig({
    plugins: lazyPlugins(() => [
        // ...
    ]),
    lint: {
        ignorePatterns: ['vendor/**', 'bootstrap/ssr/**'],
        options: {
            denyWarnings: true,
            typeAware: true,
        },
    },
    fmt: {
        printWidth: 80,
        tabWidth: 4,
        singleQuote: true,
        semi: true,
        sortTailwindcss: {
            functions: ['clsx', 'cn', 'cva'],
            entryPoint: 'resources/css/app.css',
        },
    },
});

Two details in there deserve attention. denyWarnings: true means warnings fail the build, which is the correct default and one almost nobody enabled in the old ESLint world because the config was already exhausting. And sortTailwindcss replaces prettier-plugin-tailwindcss, class sorting included, aware of clsx and cva call sites. That plugin was half the reason Prettier survived in my projects as long as it did.

The parts that aren’t free

I don’t want to write an ad here, so let me list what this costs you.

Oxlint doesn’t run your custom ESLint rules. If your team wrote bespoke rules, or leans on a niche plugin that hasn’t been ported, vp check won’t replace it and you’ll be running both linters side by side for a while. That’s not hypothetical. I did exactly this dance when I swapped ESLint for Biome earlier this year, and the awkward dual-linter period lasted about six weeks before I decided the custom rules weren’t worth keeping.

Type-aware linting is on by default, which is great for correctness and less great for people who liked their lint step finishing in under a second on giant codebases. It’s still fast, it’s just not the “did that even run” fast that plain Oxlint is.

And existing projects don’t migrate themselves. New apps generated from the starter kits get all of this automatically, but for anything already in production, VoidZero ships a vp migrate command with a warning in the migration guide that complex projects may need manual follow-up. Having done the Vite-to-Webpack math in the other direction, I’d budget an afternoon, not the fifteen minutes the happy path suggests.

Per-kit details worth knowing

The React kit moved to @vitejs/plugin-react v6 and now runs the React Compiler through @rolldown/plugin-babel rather than the plugin’s own babel option. If you’ve patched the compiler config in an existing project, that’s the spot that changed. The Svelte kit swapped the abandoned lucide-svelte for the supported @lucide/svelte. The Livewire kit barely changed at all, two files, because there’s no TypeScript to lint. Sometimes the boring stack wins again.

I maintain a couple of client apps built on these kits through my freelance work, and my plan is to migrate the internal ones first, let them soak for a month, and only then touch anything a client invoices depend on. The starter kit change tells you where Laravel is headed. It doesn’t obligate you to sprint there.

Why Laravel moving first matters

Laravel has a habit of making tooling decisions for you, and historically that’s been the framework’s best feature wearing its most annoying disguise. Sail decided Docker for you. Pint decided PHP formatting for you. Forge and Cloud decide deployment for you if you let them. Each time, some fraction of the community grumbles about lock-in, and each time, the default quietly becomes what everyone’s junior hires learn first.

That’s the real story here, more than any individual tool swap. The frontend JavaScript ecosystem has spent a decade making every new project start with an hour of tooling liturgy: pick a linter, pick a formatter, make them agree with each other, make them agree with your editor, add the Tailwind sorting plugin, add the import sorting plugin, pin everything because a minor bump broke CI that one time. None of that hour produced anything a user will ever see. Laravel deciding that a fresh app should skip the whole ceremony is the framework doing what frameworks are for.

There’s also a quieter economic angle I can’t verify yet but will be watching. Vite+ is VoidZero’s commercial product in the making. The beta is free, and the open source pieces underneath it (Vite, Rolldown, Oxc) stay open source, but the unified CLI is clearly where the paid tier will eventually live, most likely priced for teams and monorepos. Laravel adopting it as the default puts a lot of small apps on the free path of a tool with a business model attached. I don’t think that’s sinister. I do think anyone who remembers the Docker Desktop licensing surprise should keep one eyebrow raised and their old config files in git history.

My honest bet: in a year, nobody generating a new Laravel app will think about any of this, the same way nobody thinks about Mix anymore. The people with feelings about it will be the ones maintaining the in-between apps, the ones born in the ESLint era and too busy earning revenue to migrate. If that’s you, there’s no fire. ESLint and Prettier didn’t stop working this week. You’ve just been shown, fairly clearly, which direction the escalator is moving.

Try it this week

Generate a throwaway app with laravel new --react, open vite.config.ts, and run vp check against some deliberately ugly code. Then run vp migrate on a branch of one of your smaller existing projects and read the diff before you commit to anything. The diff will tell you more about your project’s weird corners than any changelog can.