Jonathan Bird Web Development

How to Fix "Vite Manifest Not Found" Error in Laravel 12 (2026 Guide)

Last updated: February 24, 2026

If you've just deployed your Laravel application (or even started a fresh development environment) and you're staring at a "Vite manifest not found" error, don't worry. This is one of the most common issues Laravel developers run into, and it's almost always a quick fix once you understand what's going on.

In this guide, I'll walk you through what causes the Vite manifest error, how to diagnose it, and the various ways to fix it in Laravel 12 and Laravel 13. Whether you're dealing with a missing build, a misconfigured path, or a production deployment issue, I've got you covered in this article.

What is the Vite Manifest Error?

When you use the @vite Blade directive in your templates, Laravel needs to read a file called build/manifest.json (inside your public directory) to figure out which compiled CSS and JavaScript files to include. This manifest file maps your source files to their compiled, versioned counterparts.

If Laravel can't find this manifest file, you'll see an error like:

1Vite manifest not found at: /path/to/your/project/public/build/manifest.json

Or in older setups that still reference Laravel Mix:

1The Mix manifest does not exist.

The Mix variant of this error is the same concept - Laravel is looking for public/mix-manifest.json and can't find it. If you've recently upgraded from Mix to Vite (which became the default in Laravel 9.19+), you might see either error depending on what's in your Blade templates.

Common Causes of the Vite Manifest Error

Before jumping into fixes, it helps to understand why this error occurs in the first place.

Assets Haven't Been Built

The most common cause by far. The manifest file is generated when you run npm run build (for production) or npm run dev (for development). If you've never run either command, or if you've just cloned a fresh project, the manifest file simply doesn't exist yet.

Running the Dev Server vs Building for Production

Vite works differently depending on whether you're in development or production mode:

  • Development: npm run dev starts a hot-reloading dev server. The @vite directive connects directly to this dev server, and no manifest file is needed.
  • Production: npm run build compiles everything and generates the manifest file. The @vite directive reads from this manifest.

The error often appears when the dev server isn't running in development, or when assets haven't been built for production.

Incorrect Build Output Path

If your vite.config.js has a custom build.outDir or build.manifest configuration, the manifest file might end up somewhere Laravel doesn't expect it.

Deployment Pipeline Missing the Build Step

Many developers forget to include npm run build in their deployment process. The application gets deployed with all the PHP code but none of the compiled frontend assets.

Node Modules Not Installed

If node_modules doesn't exist (common after a fresh clone or deployment), you can't build anything. The build command will fail silently or throw errors that get overlooked.

How to Fix the Vite Manifest Error

Let's work through the solutions from most common to more advanced scenarios.

Fix 1: Install Dependencies and Build Assets

This is the first thing to check. Run these commands in your project root:

1npm install
2npm run build

For development, start the Vite dev server instead:

1npm install
2npm run dev

After running npm run build, verify the manifest file was created:

1ls -la public/build/manifest.json

You should see the file, and its contents will look something like this:

1{
2 "resources/js/app.js": {
3 "file": "assets/app-4ed993c7.js",
4 "isEntry": true,
5 "src": "resources/js/app.js",
6 "css": [
7 "assets/app-3b8eee48.css"
8 ]
9 },
10 "resources/css/app.css": {
11 "file": "assets/app-3b8eee48.css",
12 "src": "resources/css/app.css"
13 }
14}

Fix 2: Check Your Blade Templates

Make sure your Blade templates use the @vite directive correctly. This should be in your main layout file (typically resources/views/layouts/app.blade.php):

1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1">
6 
7 @vite(['resources/css/app.css', 'resources/js/app.js'])
8</head>
9<body>
10 @yield('content')
11</body>
12</html>

If you've upgraded from Laravel Mix, make sure you've replaced the old directives:

1{{-- OLD: Laravel Mix (remove these) --}}
2<link rel="stylesheet" href="{{ mix('css/app.css') }}">
3<script src="{{ mix('js/app.js') }}"></script>
4 
5{{-- NEW: Vite (use this instead) --}}
6@vite(['resources/css/app.css', 'resources/js/app.js'])

If you're still using Mix intentionally, make sure you run:

1npx mix

And that public/mix-manifest.json exists.

Fix 3: Verify Your Vite Configuration

Check your vite.config.js in the project root. A standard Laravel setup looks like this:

1import { defineConfig } from 'vite';
2import laravel from 'laravel-vite-plugin';
3 
4export default defineConfig({
5 plugins: [
6 laravel({
7 input: ['resources/css/app.css', 'resources/js/app.js'],
8 refresh: true,
9 }),
10 ],
11});

Key things to check:

The input array matches your @vite directive. If your Blade template references resources/js/app.js but your Vite config points to resources/js/main.js, the build will work but the manifest won't have the entries Laravel expects.

The Laravel plugin is installed. Check your package.json for laravel-vite-plugin:

1npm list laravel-vite-plugin

If it's missing, install it:

1npm install --save-dev laravel-vite-plugin

No conflicting build.outDir setting. If you've customised this, make sure the @vite directive knows where to look (more on this in the advanced section).

Fix 4: Fix Development vs Production Confusion

This catches a lot of people out. The behaviour is different depending on your environment:

In development (APP_ENV=local):

The @vite directive first tries to connect to the Vite dev server (usually at http://localhost:5173). If it can't connect, it falls back to reading the manifest file. If neither is available, you get the error.

Your workflow should be:

1# Terminal 1: Run Laravel
2php artisan serve
3 
4# Terminal 2: Run Vite dev server
5npm run dev

In production (APP_ENV=production):

The @vite directive reads directly from the manifest file. You must run npm run build before deploying.

If you're seeing the error in development and don't want to run the dev server, you can build once:

1npm run build

This creates the manifest file, and your app will use the compiled assets. You just won't get hot reloading.

Fix 5: Update Your Deployment Pipeline

Make sure your deployment process includes the build step. Here's what the essential steps look like:

Basic deployment script:

1# Pull latest code
2git pull origin main
3 
4# Install PHP dependencies
5composer install --no-dev --optimize-autoloader
6 
7# Install Node dependencies and build
8npm ci
9npm run build
10 
11# Laravel optimisations
12php artisan config:cache
13php artisan route:cache
14php artisan view:cache
15 
16# Restart workers if needed
17php artisan queue:restart

Laravel Forge: Add this to your deploy script:

1npm ci
2npm run build

Using CI/CD (GitHub Actions example):

1- name: Install Node dependencies
2 run: npm ci
3 
4- name: Build assets
5 run: npm run build
6 
7- name: Deploy
8 run: # your deployment command

Docker: Add the build step to your Dockerfile:

1# Install Node and build assets
2RUN npm ci && npm run build
3 
4# Remove node_modules to reduce image size (optional)
5RUN rm -rf node_modules

The key point: npm ci (not npm install) is preferred for production and CI environments. It's faster and installs exact versions from package-lock.json.

Fix 6: Handle the Error Gracefully

If you're building a package or working on an application where frontend assets might not always be present (for example, an API-only deployment), you can suppress the error.

In your AppServiceProvider:

1use Illuminate\Support\Facades\Vite;
2 
3public function boot(): void
4{
5 // Don't throw an exception if the Vite manifest is missing
6 Vite::useManifestFilename('build/manifest.json');
7 
8 // Or suppress entirely in specific environments
9 if ($this->app->environment('testing')) {
10 Vite::withoutAssets();
11 }
12}

Debugging Vite Issues

If you're still seeing the error after trying these fixes, here are some debugging steps.

Check the Manifest File Location

Run this from your project root:

1find public -name "manifest.json" -o -name "mix-manifest.json"

If the file exists but in an unexpected location, you've likely got a custom build configuration that needs adjusting.

Verify the Vite Dev Server

If you're in development, check if the dev server is actually running:

1curl http://localhost:5173

If you get a connection refused error, the dev server isn't running. Start it with npm run dev.

If the port is different from the default, check your vite.config.js for a custom server.port setting and make sure it matches what Laravel expects.

Check for Build Errors

Run the build command manually and watch for errors:

1npm run build 2>&1

Common build failures include missing dependencies, syntax errors in your JavaScript or CSS files, or incompatible Node.js versions.

Verify Node.js Version

Vite requires Node.js 18 or higher. Check your version:

1node --version

If you're on an older version, upgrade Node.js. Using a version manager like nvm makes this straightforward:

1nvm install 22
2nvm use 22

Clear Everything

Sometimes cached state causes issues:

1# Remove compiled assets
2rm -rf public/build
3 
4# Remove node_modules and reinstall
5rm -rf node_modules
6npm ci
7 
8# Rebuild
9npm run build
10 
11# Clear Laravel caches
12php artisan config:clear
13php artisan cache:clear
14php artisan view:clear

Special Cases

Deploying to Shared Hosting

If you're on shared hosting where you can't run npm commands, build locally and commit the compiled assets:

1npm run build
2git add public/build -f
3git commit -m "Build production assets"
4git push

Add public/build to your .gitignore exception:

1/public/build
2!/public/build

This isn't ideal but works when you have no other option.

SSR (Server-Side Rendering)

If you're using Vite's SSR mode with Inertia or similar, you'll need an additional build step:

1npm run build
2npm run build:ssr

And make sure your vite.config.js has SSR configured:

1export default defineConfig({
2 plugins: [
3 laravel({
4 input: 'resources/js/app.js',
5 ssr: 'resources/js/ssr.js',
6 refresh: true,
7 }),
8 ],
9});

Using a CDN

If you're serving assets from a CDN, you need to tell Vite the base URL. In your .env:

1ASSET_URL=https://cdn.yourdomain.com

And in vite.config.js:

1export default defineConfig({
2 plugins: [
3 laravel({
4 input: ['resources/css/app.css', 'resources/js/app.js'],
5 refresh: true,
6 }),
7 ],
8 build: {
9 manifest: true,
10 },
11});

The manifest file still needs to be in public/build/ on your server - it's only the compiled assets that get served from the CDN.

Multiple Entry Points

If your application has multiple entry points (for example, separate admin and public frontends):

1// vite.config.js
2export default defineConfig({
3 plugins: [
4 laravel({
5 input: [
6 'resources/css/app.css',
7 'resources/js/app.js',
8 'resources/css/admin.css',
9 'resources/js/admin.js',
10 ],
11 refresh: true,
12 }),
13 ],
14});
1{{-- Public layout --}}
2@vite(['resources/css/app.css', 'resources/js/app.js'])
3 
4{{-- Admin layout --}}
5@vite(['resources/css/admin.css', 'resources/js/admin.js'])

All entry points end up in the same manifest file, so one npm run build handles everything.

Summary

The Vite manifest error in Laravel is almost always caused by assets not being built. Here's a quick checklist:

  1. Run npm install and npm run build to generate the manifest file
  2. Use @vite directive in your Blade templates (not the old Mix helpers)
  3. Check your vite.config.js to make sure input paths match your templates
  4. Run npm run dev during development for hot reloading
  5. Include npm ci && npm run build in your deployment pipeline
  6. Verify Node.js 18+ is installed on your build environment

Vite is a massive improvement over Laravel Mix in terms of speed and developer experience. Once you've got it configured correctly, you'll rarely think about it again.


Having trouble with Vite or other Laravel issues? I specialise in Laravel development and debugging complex application issues. Get in touch to discuss your project.

Topics

Syntax highlighting by Torchlight

More articles

How to Fix "SQLSTATE[42S22]: Column Not Found" Error in Laravel 12 (2026 Guide)

The "Column not found: 1054 Unknown column" error is one of the most common database issues in Laravel. Learn how to diagnose and fix it, whether it's a typo, a missing migration, or an Eloquent relationship issue.

Read article

How to Use the Laravel AI SDK (2026 Guide)

I've been building with Laravel's new first-party AI SDK and it just clicks. Here's everything I learned, from your first agent to testing it all with fake().

Read article

Talk to me about your website project