LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 2719 min read

Customizing Bootstrap with Sass

Learn how to customize Bootstrap by overriding Sass variables like $primary and recompiling your own custom build.

Introduction

Every color, font, spacing value, and border radius in Bootstrap is driven by a Sass variable. Instead of fighting the compiled CSS with !important overrides, you can install Bootstrap's Sass source, set your own values for those variables before Bootstrap defines them, and compile a build that is Bootstrap through and through but themed to match your brand.

What You Will Learn
  • Why overriding Sass variables beats overriding compiled CSS.
  • Setting up a project that compiles Bootstrap from source.
  • Overriding core variables like $primary and $font-family-base.
  • Importing only the Bootstrap modules you actually use.
  • Adding a brand-new custom theme color.

Why Customize with Sass

When you override CSS after the fact, you're fighting specificity and duplicating rules Bootstrap already wrote — every component that uses $primary needs its own manual override. When you override the Sass variable itself, every component built on top of it (buttons, links, badges, form focus rings, and more) updates automatically, because Bootstrap's own source code references that variable throughout.

Project Setup

Install Bootstrap and the Sass compiler as dev dependencies, then create your own entry .scss file instead of linking Bootstrap's prebuilt CSS.

npm install bootstrap sass --save-dev
project/
├── scss/
│ └── custom.scss
├── index.html
└── package.json

Overriding Variables

Bootstrap's variables all have !default flags, which means they only apply if nothing has set a value already. Declare your own values above the line that imports Bootstrap's variables, and yours will win.

// scss/custom.scss
// 1. Your variable overrides FIRST
$primary: #6f42c1;
$secondary: #495057;
$font-family-base: 'Inter', system-ui, sans-serif;
$border-radius: 0.5rem;
$enable-rounded: true;
// 2. THEN import Bootstrap itself
@import "../node_modules/bootstrap/scss/bootstrap";
Order Matters

Your overrides must appear BEFORE the @import "bootstrap" line. Sass's !default only skips a value if the variable was already set earlier in the compile — importing Bootstrap first locks in its defaults and your later overrides will be ignored.

Importing Only What You Need

Instead of the single "bootstrap" import, you can import individual partials to shrink your final CSS bundle to only the components you actually use.

// Required
@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/variables-dark";
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";
// Only the pieces this project uses
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/utilities";
@import "../node_modules/bootstrap/scss/utilities/api";

Adding a Custom Theme Color

Bootstrap generates utility classes and component variants (like .btn-brand or .text-brand) from a Sass map called $theme-colors. Add your own entry to that map before importing Bootstrap to get a fully-integrated new color, complete with button, badge, alert, and text variants.

@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
$theme-colors: map-merge($theme-colors, (
"brand": #ff6b35,
));
@import "../node_modules/bootstrap/scss/bootstrap";
<button class="btn btn-brand">Brand Button</button>
<span class="badge text-bg-brand">New</span>

Compiling the Build

Compile the .scss file to a regular .css file using the Sass CLI, then link that output file exactly as you would the Bootstrap CDN CSS.

npx sass scss/custom.scss dist/custom.css
# or watch for changes during development:
npx sass --watch scss/custom.scss dist/custom.css
<link rel="stylesheet" href="dist/custom.css">

Common Mistakes

Avoid These Mistakes
  • Placing variable overrides AFTER the @import "bootstrap" line, so !default silently ignores them.
  • Editing Bootstrap's own node_modules source files directly instead of overriding variables — those edits vanish on the next npm install.
  • Forgetting the functions, variables, and mixins partials when doing a selective import, causing undefined variable/mixin errors.
  • Not recompiling after changing a variable and wondering why the page still looks unchanged.

Best Practices

  • Keep all your variable overrides together at the top of one file, before the Bootstrap import, so they are easy to find and update.
  • Use selective imports in production to ship less CSS than the full Bootstrap bundle.
  • Add new brand colors to $theme-colors rather than hand-writing your own button/badge classes.
  • Check Bootstrap's official _variables.scss source to see the full list of overridable variables and their defaults.
  • Recompile automatically with a watch task or your bundler's Sass loader during development.

Frequently Asked Questions

No — the Sass CLI (npx sass) alone is enough to compile a .scss file to .css. A bundler is only needed if you want Sass compilation integrated into a larger app build pipeline.

Only with CSS custom property overrides for a few surface-level tweaks (like --bs-primary in newer Bootstrap versions) — for deep changes that cascade through every component, Sass compilation is the reliable approach.

Yes, as long as you keep updating the bootstrap npm package and recompiling — you are building from the same source, just with your own variable values applied on top.

Key Takeaways

  • Bootstrap's Sass variables use !default, so overrides must be set before Bootstrap is imported.
  • A selective import only pulls in the partials your project actually uses, reducing bundle size.
  • Adding to the $theme-colors map generates full button/badge/text/alert variants automatically.
  • The Sass CLI (npx sass) compiles your custom .scss into a regular .css file to link in HTML.

Summary

Overriding Sass variables is the proper way to theme Bootstrap — it keeps every component consistent and lets you trim the CSS you ship, instead of layering fragile overrides on top of the compiled defaults. Next, you will look at how Bootstrap's JavaScript components work under the hood, comparing data-attribute initialization to manual JS setup.

Next Lesson →

Bootstrap JavaScript Components