Building a Custom Bootstrap 5 Bundle: Import Only the Components You Need

Building a Custom Bootstrap 5 Bundle: Import Only the Components You Need

Key Takeaways

  • The Bootstrap 5 Sass source is organised into discrete partials, making selective imports straightforward.
  • A custom build starts with overriding variables before any Bootstrap partial is loaded, not after.
  • Removing unused components, utilities, and JavaScript plugins independently gives you three separate size levers.
  • A Sass-based build pipeline (Dart Sass 1.x) is the only officially supported compiler for Bootstrap 5.3+.
  • PurgeCSS is a complementary, not alternative, strategy and works best after you have already done selective imports.

Why a Custom Build Matters in 2025

Bootstrap 5 ships as a convenience. Its precompiled CSS includes every component from accordions to tooltips so teams can prototype without a build step. That convenience has a cost. The full stylesheet includes roughly 200 component classes, 1,700-plus utility classes, and CSS custom property declarations for every breakpoint. For a landing page that uses a navbar, a hero section, cards, and a contact form, you are delivering CSS for carousels, offcanvases, badges, toasts, and dozens of other things the visitor’s browser will never use.

Page speed directly affects Core Web Vitals scores. A leaner CSS payload reduces render-blocking time and Largest Contentful Paint. If you are working inside a premium template like the Canvas HTML Template, the Sass source is already structured so your custom overrides sit neatly above Bootstrap’s own imports, making a selective build cleaner to maintain.

Building a Custom Bootstrap 5 Bundle: Import Only the Components You Need, abstract concept illustration

Setting Up Your Sass Environment

Bootstrap 5.3 requires Dart Sass 1.57.0 or higher. The legacy Node Sass (LibSass) compiler reached end-of-life and is explicitly unsupported. Install the official package:

npm install --save-dev sass

Next, install Bootstrap itself as a package so you can reference its source partials directly:

npm install bootstrap@5.3

Your project’s entry Sass file (typically custom.scss) sits at the root of your src/scss folder. All imports flow through this single file. If you are using a task runner or bundler, point it at this entry file. The post Gulp vs Vite vs Webpack for HTML Template Workflows covers the toolchain options in detail if you need to choose between them.

Understanding the Bootstrap 5 Sass Import Map

Bootstrap’s own bootstrap.scss is simply a list of @import statements. The structure, in order, is:

  • Functions, required, must come first.
  • Variables, default values; override before this line takes effect.
  • Maps, colour maps, grid breakpoints, and spacing scales.
  • Mixins, required for components that call them.
  • Utilities API, the engine for utility classes.
  • Layout, containers, grid, columns, gutters.
  • Content, typography, images, tables.
  • Forms, inputs, labels, selects, checks, ranges.
  • Components, buttons, cards, modals, navbars, etc.
  • Helpers, clearfix, ratio, stacks, visually-hidden.
  • Utilities, the generated utility classes.

The first four groups (functions, variables, maps, mixins) are almost always required in full. The components group is where the bulk of the savings come from.

Writing Your Custom Entry File

The pattern is straightforward: import Bootstrap internals in the correct order, comment out every component you do not use, and keep your own variable overrides between the variables import and the rest of Bootstrap. Here is a minimal example for a marketing site that needs a navbar, hero, cards, and a contact form:

// 1. Your variable overrides (MUST come before Bootstrap variables)
$primary: #4f46e5;
$font-size-base: 1rem;
$border-radius: 0.375rem;

// 2. Bootstrap required internals
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/utilities";

// 3. Layout — keep grid and containers
@import "bootstrap/scss/containers";
@import "bootstrap/scss/grid";

// 4. Content — keep only what you need
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/type";
@import "bootstrap/scss/images";
// @import "bootstrap/scss/tables"; // not needed

// 5. Forms
@import "bootstrap/scss/forms";
// @import "bootstrap/scss/input-group"; // not needed

// 6. Components — comment out everything unused
@import "bootstrap/scss/buttons";
@import "bootstrap/scss/nav";
@import "bootstrap/scss/navbar";
@import "bootstrap/scss/card";
// @import "bootstrap/scss/accordion";
// @import "bootstrap/scss/breadcrumb";
// @import "bootstrap/scss/carousel";
// @import "bootstrap/scss/modal";
// @import "bootstrap/scss/offcanvas";
// @import "bootstrap/scss/tooltip";
// @import "bootstrap/scss/popover";
// @import "bootstrap/scss/toast";

// 7. Helpers
@import "bootstrap/scss/helpers";

// 8. Utilities (generated classes)
@import "bootstrap/scss/utilities/api";

Commenting rather than deleting makes it trivial to re-enable a component when requirements change. It also makes code reviews clearer: anyone reading the file can see exactly which parts of Bootstrap are in scope.

Trimming the Utilities API

The generated utility classes alone account for a large share of Bootstrap’s output. Bootstrap 5 gives you a map-based configuration API to disable entire utility categories. Place this override before the utilities/api import:

// Disable utility categories you don't use
$utilities: map-merge(
  $utilities,
  (
    "float": null,
    "overflow": null,
    "shadow": null,
    "opacity": null
  )
);

@import "bootstrap/scss/utilities/api";

Setting a utility key to null removes that group entirely from the compiled output. Common candidates for removal are float utilities (largely obsolete with flexbox), overflow utilities, and the verbose shadow scale if you apply shadows manually.

Trimming the JavaScript Bundle

CSS is only half the equation. Bootstrap’s JavaScript bundle includes handlers for dropdowns, modals, tooltips, popovers, offcanvases, carousels, scrollspy, tabs, toasts, and collapses. If your project uses only dropdowns and collapse, import those modules individually via ES modules rather than the full bundle:

import Dropdown from 'bootstrap/js/dist/dropdown';
import Collapse from 'bootstrap/js/dist/collapse';

This matters most when you bring in third-party plugins. If you are using GLightbox for image and video lightboxes, you are already pulling in a separate JS file, so there is no reason to keep Bootstrap’s Modal JS loaded alongside it. Likewise, if you bring in Swiper.js for sliders, Bootstrap’s Carousel JS can go.

PurgeCSS: Complement, Not Substitute

PurgeCSS scans your HTML and JavaScript for class names that appear in your stylesheet, then removes any declaration whose selector is never referenced. It is a powerful tool, but not a substitute for selective imports. Two reasons:

  • Dynamically added classes injected by JavaScript plugins (tooltips, modals, carousel active states) may not appear in static HTML and will be purged incorrectly without a careful safelist configuration.
  • Build time is longer when PurgeCSS has to scan a large compiled stylesheet versus a smaller one produced by selective imports.

The correct order is: selective imports first to remove components you know you do not need, then PurgeCSS as a second pass to catch remaining unused declarations within the components you kept. Together, the two techniques can bring a compiled stylesheet below 20 KB for focused landing pages.

Frequently Asked Questions

No, provided you include the Sass partials that correspond to the JS components you keep. If you import modal.js you must also import bootstrap/scss/modal. The JS depends on class names the CSS defines, so removing the CSS partial while keeping the JS will produce broken UI behaviour.

A CDN link always delivers the full precompiled stylesheet. There is no CDN option for a selective build. If file size is a concern and you want variable overrides to take effect at compile time rather than via CSS custom property overrides at runtime, a local Sass build is the only path.

Functions, variables, variables-dark (Bootstrap 5.3+), maps, mixins, and the reboot partial are effectively required for a coherent output. Removing functions or mixins will cause Sass compilation errors because other partials depend on them. Removing reboot leaves browser inconsistencies unaddressed.

Bootstrap 5.3 still uses @import internally. The Bootstrap team has noted that migrating to @use and @forward would be a significant breaking change and has not committed to a timeline. For now, @import in your entry file is the correct and officially documented approach.

Results vary by project scope. A content marketing site using the grid, type, buttons, navbar, and cards typically compiles to 45 to 65 KB uncompressed, compared to roughly 230 KB for the full Bootstrap stylesheet. Adding PurgeCSS on top can bring that figure below 25 KB. JavaScript savings are proportional: removing eight of Bootstrap’s eleven plugins reduces the JS bundle by approximately 60 percent.

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