Menü schliessen
Created: July 16th 2025
Categories: Laravel
Author: Miljan Puzovic

Creating manual chunks in Laravel Vite

Tags:  build,  chunks,  Laravel,  Laravel Vite,  vite
Donation Section: Background
Monero Badge: QR-Code
Monero Badge: Logo Icon Donate with Monero Badge: Logo Text
82uymVXLkvVbB4c4JpTd1tYm1yj1cKPKR2wqmw3XF8YXKTmY7JrTriP4pVwp2EJYBnCFdXhLq4zfFA6ic7VAWCFX5wfQbCC

Manual chunks allow you to control how your JavaScript and CSS bundles are split, which improves loading performance by enabling better caching strategies and parallel downloads.

Benefits

  1. Better caching - Vendor libraries change less frequently than your app code, so they can be cached longer
  2. Parallel loading - Browser can download multiple chunks simultaneously
  3. Faster rebuilds - Only changed chunks need to be rebuilt during development
  4. Smaller initial bundle - Code is split across multiple files

Let's say that we have some basic Laravel Vite setup in vite.config.js file:

import {
  defineConfig,
} from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
    laravel({
      input: [
        'resources/sass/app.scss',
        'resources/js/app.js',
      ],
      refresh: [
        'resources/routes/**',
        'routes/**',
        'resources/views/**',
      ],
    }),
  ],
});

If we run npm run build in our terminal the size of the chunks that we're getting is going to be proportional to the size of our JavaScript and CSS code and the amount of the external libraries. In our case we're getting

public/build/assets/app-BRINWwLo.css 49.47 kB │ gzip: 9.01 kB
public/build/assets/app-d9i94Heu.css 215.76 kB │ gzip: 33.14 kB
public/build/assets/app-BLcXt5zv.js 742.44 kB │ gzip: 218.88 kB

where 742.44 kB is quite large and exceeds the default 500 kB threshold.

but if we use build.rollupOptions.output.manualCunks we can actually split those chunks into app (default chunk), vendor and helpers. We are putting all third-party libraries into vendor chunk and our helper functions into helpers chunk. All these third-party libraries and our helpers functions are already included into our project even, splitting them into different chunks is just something that we do in addition.

import {
  defineConfig,
} from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
    laravel({
      input: [
        'resources/sass/app.scss',
        'resources/js/app.js',
      ],
      refresh: [
        'resources/routes/**',
        'routes/**',
        'resources/views/**',
      ],
    }),
  ],
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'vendor': [
            'swiper',
            'swiper/modules',
            'tom-select/popular',
            'tippy.js',
            'flatpickr',
            'flatpickr/dist/l10n/de.js',
            'notiflix',
            'signature_pad',
            '@simonwep/pickr',
          ],
          'helpers': [
            'resources/js/helpers'
          ]
        }
      }
    }
  },
});

and in our new build our chunks are looking like this

public/build/assets/app-BpyN-xUC.css 10.64 kB │ gzip: 3.58 kB
public/build/assets/helpers-CTsDN5zy.css 38.83 kB │ gzip: 5.73 kB
public/build/assets/app-d9i94Heu.css 215.76 kB │ gzip: 33.14 kB
public/build/assets/app-CcY5hVFp.js 113.37 kB │ gzip: 29.29 kB
public/build/assets/helpers-7MjohEP4.js 290.35 kB │ gzip: 95.19 kB
public/build/assets/vendor-Ctz8cOPR.js 339.79 kB │ gzip: 95.64 kB