Setting Up Vite for a Bootstrap 5 HTML Template Build

Setting Up Vite for a Bootstrap 5 HTML Template Build

Vite is now the build tool of choice for developers who want near-instant dev-server startup, native ES module hot-module replacement, and a lean production bundle. If you are working with a Bootstrap 5 HTML template and still relying on a slow webpack config or a legacy Gulp pipeline, switching to Vite will cut your compile times dramatically and simplify your project structure at the same time. This guide walks through a complete, production-grade Vite setup for Bootstrap 5 in 2025, covering SCSS compilation, JS bundling, and the specific adjustments needed when working with a premium template like the Canvas HTML Template.

Key Takeaways

  • Vite 5 starts a dev server in under 300 ms on most machines because it skips bundling during development.
  • Bootstrap 5 SCSS can be compiled through Vite using the vite-plugin-sass or the built-in preprocessorOptions config, with full support for @use and @forward.
  • Correctly aliasing Bootstrap’s JavaScript ensures tree-shaking works and avoids duplicate bundle entries.
  • A vite.config.js with a root pointing to your HTML source directory makes multi-page template builds straightforward.
  • Production builds output hashed, minified assets automatically. Pair this with PurgeCSS for maximum file-size reduction.
  • When NOT to use Vite: if your template ship process is purely drag-and-drop delivery to a CMS with no Node pipeline, a pre-compiled template remains the simpler choice.

Why Vite for a Bootstrap 5 Project in 2025

Vite (version 5.x as of 2025) leverages native ES modules in the browser during development. The browser requests only the files it needs rather than waiting for a full bundle to compile, so the dev server starts in milliseconds regardless of project size. For Bootstrap 5 specifically, this matters because Bootstrap’s SCSS tree is large and historically slow to compile through older toolchains.

Consider the alternatives. webpack 5 still works well for complex applications, but its configuration overhead is substantial and cold-start times frequently exceed 10 seconds on larger template projects. Parcel 2 offers zero-config convenience but gives you less control over output file names and chunking strategy, which matters when a template ships dozens of HTML pages with shared assets. Gulp pipelines remain common in premium template distributions (Canvas ships one) precisely because they are framework-agnostic, but they lack HMR and require separate plugins for every task.

Vite is the right call for active development of a Bootstrap 5 template, teams wanting instant feedback loops, and projects that will eventually ship JavaScript modules. It is overkill for a simple one-page static site where you need compiled CSS once and never touch the code again.

Setting Up Vite for a Bootstrap 5 HTML Template Build, abstract concept illustration

Recommended Project Structure

Before writing a single line of config, agree on a folder layout. The structure below keeps source files separate from compiled output and mirrors what most Bootstrap 5 template distributions already use.

project-root/
├── src/
│   ├── index.html
│   ├── about.html
│   ├── scss/
│   │   ├── main.scss
│   │   └── _variables.scss
│   └── js/
│       └── main.js
├── public/
│   └── images/
├── dist/           ← generated by vite build
├── package.json
└── vite.config.js

Placing HTML files directly inside src/ and setting root: 'src' in Vite’s config tells Vite to treat those HTML files as entry points. Every <link> and <script> tag Vite finds inside them becomes part of the dependency graph automatically.

Installing Dependencies

Start with a fresh package.json or add into your existing project. You need Vite itself, Sass (the Dart Sass implementation, not the deprecated node-sass), and Bootstrap 5.

npm install --save-dev vite sass
npm install bootstrap @popperjs/core

Use Dart Sass (the sass package) rather than node-sass. Bootstrap 5.3 officially dropped support for LibSass and node-sass, and Vite’s built-in CSS preprocessor pipeline calls Dart Sass natively without an extra plugin. If your project still uses @import in SCSS, migrate to @use now. The post @use vs @import: Modernising Your Bootstrap 5 Sass Workflow covers the migration in detail.

html template build tool, abstract technical diagram

Writing the vite.config.js

The config below handles multi-page HTML input, SCSS variable injection, and a clean dist/ output.

// vite.config.js
import { defineConfig } from 'vite';
import { resolve } from 'path';

export default defineConfig({
  root: 'src',
  base: './',
  css: {
    preprocessorOptions: {
      scss: {
        // Inject your variable overrides before every SCSS file
        additionalData: @use "./scss/variables" as *;
      }
    }
  },
  build: {
    outDir: '../dist',
    emptyOutDir: true,
    rollupOptions: {
      input: {
        main:  resolve(__dirname, 'src/index.html'),
        about: resolve(__dirname, 'src/about.html')
      }
    }
  },
  resolve: {
    alias: {
      '~bootstrap': resolve(__dirname, 'node_modules/bootstrap')
    }
  }
});

The ~bootstrap alias follows the same convention used by webpack and many premium templates, so existing SCSS imports such as @use '~bootstrap/scss/bootstrap' as bs continue to work without modification. The base: './' setting outputs relative asset paths, which is essential for HTML templates opened directly from the file system rather than served from a web root.

Compiling Bootstrap 5 SCSS with Vite

Your SCSS entry file should import Bootstrap selectively rather than loading the entire stylesheet. This is where the real production-build performance comes from, and it pairs naturally with the PurgeCSS workflow described in Removing Unused CSS from Bootstrap 5 with PurgeCSS.

// src/scss/main.scss

// 1. Override Bootstrap variables before importing
@use 'variables' as *;

// 2. Bootstrap required files
@use '~bootstrap/scss/functions';
@use '~bootstrap/scss/variables' as bsvars;
@use '~bootstrap/scss/maps';
@use '~bootstrap/scss/mixins';
@use '~bootstrap/scss/utilities';

// 3. Only the Bootstrap components you actually use
@use '~bootstrap/scss/root';
@use '~bootstrap/scss/reboot';
@use '~bootstrap/scss/type';
@use '~bootstrap/scss/grid';
@use '~bootstrap/scss/buttons';
@use '~bootstrap/scss/navbar';

// 4. Utilities API must come last
@use '~bootstrap/scss/utilities/api';

If you are working with the Canvas template’s own SCSS layer, replace the Bootstrap partials above with Canvas’s equivalent entry file after checking Canvas’s documented load order. Canvas uses --cnvs-themecolor and related CSS custom properties defined in its root partial, so that partial must load before any component overrides. See the post on Theming One HTML Template for Multiple Client Brands with CSS Variables for a deeper look at working with Canvas’s variable layer.

Bundling Bootstrap 5 JavaScript

Import only the Bootstrap JS components your template uses. Importing the entire bundle defeats tree-shaking.

// src/js/main.js
import { Dropdown } from 'bootstrap';
import { Tooltip } from 'bootstrap';
import { Toast } from 'bootstrap';

// Initialise tooltips on all elements that carry the data attribute
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => {
  new Tooltip(el);
});

Vite will tree-shake unused Bootstrap components at build time, producing a smaller bundle than importing bootstrap/dist/js/bootstrap.bundle.min.js in a script tag. One trap worth knowing: bootstrap.bundle.min.js already includes Popper, but individual imports do not. If you use Dropdown, Tooltip, or Popover through named imports, you must also import Popper separately. The post on Bootstrap 5 Tooltips and Popovers: Popper Config and Common Pitfalls covers that dependency chain in full.

Link the entry script in your HTML with type="module":

<script type="module" src="/js/main.js"></script>

Vite detects the module type and routes it through Rollup for the production build.

Running the Dev Server and Building for Production

Add these scripts to package.json:

"scripts": {
  "dev":   "vite",
  "build": "vite build",
  "preview": "vite preview"
}

Run npm run dev and Vite starts a local server, typically at http://localhost:5173. SCSS changes reflect in the browser instantly via HMR without a page reload. Run npm run build to output a production-ready dist/ folder with hashed filenames, minified CSS (via Lightning CSS, Vite 5’s default minifier), and a minified JS bundle. Run npm run preview to serve the dist/ folder locally and verify the build before deployment.

A typical Bootstrap 5 project compiled with this setup produces a CSS file around 20 to 30 KB gzipped when selective imports are used, compared to 150 KB gzipped for the full Bootstrap stylesheet. For a broader look at the performance techniques that compound on top of this, see Bootstrap 5 Performance: A Complete Guide to Fast-Loading Templates.

Frequently Asked Questions

Yes. You list each HTML file as a Rollup input inside vite.config.js. For very large template distributions (50 or more pages), consider a glob helper to auto-discover all HTML files rather than listing them manually. The fast-glob package pairs well with Vite for this pattern.

You can, but running both in parallel on the same source files will cause conflicts. The cleanest approach is to adopt Vite for greenfield projects or full template reworks, while keeping the Gulp pipeline for minor maintenance on already-shipped sites. Do not point both tools at the same output directory.

Bootstrap 5.3 partially still uses older Sass division syntax in some partials. Dart Sass 1.65 and later emit deprecation warnings for this. They are warnings, not errors, and the compiled output is correct. Bootstrap 6 will resolve these at the source level. In the meantime, you can silence the warnings with quietDeps: true inside preprocessorOptions.scss.

Place font files inside the public/ folder so Vite copies them to dist/ unchanged. Update the @font-face src paths in your SCSS to use an absolute path from the web root, such as /fonts/bootstrap-icons.woff2. Alternatively, reference the fonts from a CDN to keep your build output smaller.

Absolutely. Vite is a build-time tool only. The dist/ output is plain HTML, CSS, and JavaScript with no Node dependency at runtime. Upload the contents of dist/ to any shared host via FTP exactly as you would upload any static HTML template.

Looking for a production-ready Bootstrap 5 HTML template? Browse Canvas Template demos and find the perfect starting point for your next project.

If you’re building with the Canvas HTML Template and want to ship production-ready Bootstrap 5 layouts faster, try Canvas Builder free — the visual builder that exports clean Canvas-ready markup in minutes.

Skip the setup and build it free

Spin up a complete Bootstrap 5 site, blog included, with Canvas Builder. No coding, no cost.

Share:
Canvas Team
Canvas Team

Tutorials and tips for building beautiful Bootstrap 5 websites with the Canvas HTML Template and Canvas Builder.

More from the Canvas Blog