Jesse A. Green / notebook

Bootstrap — Administrator & Developer Guide

Generated May 2026 from twbs/bootstrap at 5d302a0

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Bootstrap 5.3.8 is the most popular HTML, CSS, and JS front-end framework for responsive, mobile-first web development. This guide covers the architecture, build system, configuration surface, deployment strategies, and internal design patterns that administrators, integrators, and contributing developers need to operate and extend Bootstrap effectively.

For installation walkthroughs, component usage examples, and everyday development tasks, see the companion User Guide.


1. Architecture Overview

1.1 High-Level Layer Diagram

┌─────────────────────────────────────────────────────────┐
│                     Consumer Code                        │
│          (HTML markup + data-bs-* attributes)            │
├─────────────────────────────────────────────────────────┤
│                    Entry Points                          │
│   js/index.esm.js (ES modules)  js/index.umd.js (UMD)  │
├─────────────────────────────────────────────────────────┤
│                  Plugin Components                       │
│  Alert │ Button │ Carousel │ Collapse │ Dropdown │ Modal │
│  Offcanvas │ ScrollSpy │ Tab │ Toast │ Tooltip │Popover │
├─────────────────────────────────────────────────────────┤
│               BaseComponent (base-component.js)          │
│                    VERSION = '5.3.8'                     │
├─────────────────────────────────────────────────────────┤
│                Config (config.js) base class             │
├────────────────┬────────────────────────────────────────┤
│   DOM Layer    │          Utility Layer                  │
│  data.js       │  backdrop.js    focustrap.js            │
│  event-handler │  sanitizer.js   scrollbar.js            │
│  manipulator   │  swipe.js       template-factory.js     │
│  selector-eng  │  component-functions.js   index.js      │
├────────────────┴────────────────────────────────────────┤
│                    SCSS Layer                             │
│  scss/bootstrap.scss → _variables → _maps → _mixins     │
│  → _root → _reboot → component partials → _utilities    │
├─────────────────────────────────────────────────────────┤
│               Build Tooling                              │
│  Sass → PostCSS/Autoprefixer → RTLCSS → clean-css       │
│  Rollup → Babel → Terser                                 │
│  Astro 5.18.1 (docs site SSG)                            │
└─────────────────────────────────────────────────────────┘

1.2 Component Inventory

Component Source File Dependencies Default Config Keys
Alert js/src/alert.js — —
Button js/src/button.js — —
Carousel js/src/carousel.js Swipe interval, keyboard, pause, ride, touch, wrap
Collapse js/src/collapse.js — parent, toggle
Dropdown js/src/dropdown.js Popper autoClose, boundary, display, offset, popperConfig, reference
Modal js/src/modal.js Backdrop, FocusTrap, ScrollBarHelper backdrop, focus, keyboard
Offcanvas js/src/offcanvas.js Backdrop, FocusTrap, ScrollBarHelper backdrop, keyboard, scroll
Popover js/src/popover.js (inherits Tooltip) (extends Tooltip defaults)
ScrollSpy js/src/scrollspy.js — —
Tab js/src/tab.js — —
Toast js/src/toast.js — —
Tooltip js/src/tooltip.js Popper, TemplateFactory, Sanitizer —

1.3 Class Hierarchy

Config (base) ← js/src/util/config.js
  ├── Backdrop ← js/src/util/backdrop.js
  ├── FocusTrap ← js/src/util/focustrap.js
  ├── Swipe ← js/src/util/swipe.js
  ├── TemplateFactory ← js/src/util/template-factory.js
  └── BaseComponent ← js/src/base-component.js (VERSION = '5.3.8')
       ├── Alert
       ├── Button
       ├── Carousel
       ├── Collapse
       ├── Dropdown (uses Popper)
       ├── Modal (uses Backdrop, FocusTrap, ScrollBarHelper)
       ├── Offcanvas (uses Backdrop, FocusTrap, ScrollBarHelper)
       ├── ScrollSpy
       ├── Tab
       ├── Toast
       └── Tooltip (uses Popper, TemplateFactory, Sanitizer)
            └── Popover

ScrollBarHelper ← js/src/util/scrollbar.js (standalone, no parent)

1.4 Data Flow: Component Initialization

1. DOM ready (or explicit JS call)
2. new ComponentClass(element, config)
3. Config._mergeConfigObj() resolves final config:
     Default values
       ↓ override with data-bs-config='{...}' JSON attribute
       ↓ override with individual data-bs-{key} attributes
       ↓ override with JS config object
4. Config._typeCheckConfig() validates types against DefaultType
5. BaseComponent constructor:
     a. Stores instance in DOM data store (data.js Map)
     b. Registers event listeners via EventHandler
6. Component-specific setup (show/hide state, Popper init, etc.)

1.5 Technology Stack

Layer Technology Version Constraint
CSS preprocessor Dart Sass (see dart-sass compatibility notes)
CSS post-processing PostCSS + Autoprefixer —
RTL generation RTLCSS —
CSS minification clean-css —
JS bundler Rollup —
JS transpiler Babel —
JS minifier Terser —
Docs site Astro (SSG) 5.18.1
JS testing Jasmine + Karma Chrome launcher
SCSS testing sass-true + Jasmine —
Linting ESLint, Stylelint, Prettier, lockfile-lint —
HTML validation vnu-jar —
Responsive font sizes RFS v10.0.0

2. System Requirements

2.1 Build Environment

Requirement Detail
Node.js Required for all build tasks and docs site
npm Package manager (lockfile-lint enforced)
Dart Sass SCSS compilation (sass npm package)
Git Repository management

Note

Bootstrap is a front-end framework delivered as CSS and JS. Node.js is only required if you are building from source, customizing Sass variables, or running the docs site locally. End users consuming CDN or prebuilt dist files do not need Node.js.

2.2 Browser Support

Bootstrap targets modern browsers as defined in .browserslistrc. The framework does not support Internet Explorer. All current stable versions of Chrome, Firefox, Safari, Edge, and their mobile counterparts are supported.

2.3 Sass Requirements

When compiling SCSS from source, ensure your Sass compiler supports the features used by Bootstrap 5.3.8.

Warning

Dart Sass 1.80.0+ emits deprecation warnings for certain patterns used in Bootstrap (see #40962). These are warnings only and do not affect output. Pin your Sass version or suppress warnings if they clutter your build log.

2.4 Popper.js Dependency

Dropdown, Tooltip, and Popover require @popperjs/core ^2.11.8 for positioning. If you use bootstrap.bundle.js or bootstrap.bundle.min.js, Popper is included. If you use the standalone build (bootstrap.js or bootstrap.esm.js), you must provide Popper separately.


3. Configuration Reference

3.1 Sass Variables — Theme Colors

Override these in your custom Sass file before importing Bootstrap:

// _variables.scss defaults
$primary:   #0d6efd;
$secondary: #6c757d;
$success:   #28a745;
$danger:    #dc3545;
$warning:   #ffc107;
$info:      #17a2b8;
$light:     #f8f9fa;
$dark:      #343a40;

The $theme-colors map collects these into a single map used by the utilities API, component styles, and CSS custom properties.

3.2 Sass Variables — Base Colors

$blue:      #0d6efd;
$indigo:    #6610f2;
$purple:    #6f42c1;
$pink:      #d63384;
$red:       #dc3545;
$orange:    #fd7e14;
$yellow:    #ffc107;
$green:     #198754;
$teal:      #20c997;
$cyan:      #0dcaf0;
$white:     #fff;
$gray:      #6c757d;
$gray-dark: #343a40;

3.3 Sass Variables — Gray Scale

Variable Value
$gray-100 #f8f9fa
$gray-200 #e9ecef
$gray-300 #dee2e6
$gray-400 #ced4da
$gray-500 #adb5bd
$gray-600 #868e96
$gray-700 #495057
$gray-800 #343a40
$gray-900 #212529

3.4 Sass Variables — Breakpoints

Breakpoint Variable Min-width Container Max-width
xs $grid-breakpoint-xs 0 (none — fluid)
sm $grid-breakpoint-sm 576px 540px
md $grid-breakpoint-md 768px 720px
lg $grid-breakpoint-lg 992px 960px
xl $grid-breakpoint-xl 1200px 1140px
xxl $grid-breakpoint-xxl 1400px 1320px

The $grid-breakpoints and $container-max-widths maps are the canonical sources for these values. Override the map itself to add, remove, or change breakpoints.

3.5 Sass Variables — Spacing

The spacing scale is derived from $spacer (default 1rem) and the $spacers map:

Key Value
0 0
1 $spacer * 0.25
2 $spacer * 0.5
3 $spacer
4 $spacer * 1.5
5 $spacer * 3

3.6 Sass Variables — Typography

Key typography variables include $font-family-sans-serif, $font-family-monospace, $font-size-base (default 1rem), $font-size-lg, $font-size-sm, $line-height-base (default 1.5), $headings-font-weight (default 500), and the heading size scale ($h1-font-size through $h6-font-size).

3.7 Sass Maps

Bootstrap uses Sass maps extensively. The key maps to know:

Map Purpose Location
$theme-colors All theme color values _variables.scss
$grays Gray scale values _variables.scss
$grid-breakpoints Responsive breakpoints _variables.scss
$container-max-widths Max container widths per breakpoint _variables.scss
$spacers Spacing scale _variables.scss
$utilities Utility class definitions _utilities.scss → utilities/_api.scss

Maps are merged and finalized in scss/_maps.scss. Override variables before the import chain; modify maps in _maps.scss or after it.

3.8 CSS Custom Properties

Bootstrap generates CSS custom properties (CSS variables) in :root via scss/_root.scss. These include all theme colors, body defaults, font families, and component-level tokens. Dark mode overrides these properties under [data-bs-theme="dark"].

3.9 Color Mode Configuration

Bootstrap 5.3 supports light and dark color modes via the data-bs-theme attribute:

<!-- Set on <html> for global dark mode -->
<html data-bs-theme="dark">

<!-- Set on a container for scoped dark mode -->
<div data-bs-theme="dark">
  <!-- Dark-themed content -->
</div>

Dark-mode variables are defined in scss/_variables-dark.scss. The color-mode mixin (scss/mixins/_color-mode.scss) generates the [data-bs-theme="dark"] selector rules.

Important

Dark mode applies through CSS custom property overrides, not by generating a separate stylesheet. This means a single CSS file supports both modes. Switching modes at runtime is a matter of changing the data-bs-theme attribute value via JavaScript.

3.10 Utilities API Configuration

The utilities API (scss/utilities/_api.scss) generates utility classes from the $utilities map. Each utility entry defines:

Key Type Description
property string/list The CSS property (or properties) to set
values map/list The values to generate classes for
class string Class prefix (defaults to property name)
responsive boolean Generate responsive variants (-sm, -md, etc.)
rfs boolean Apply RFS (responsive font sizing)
print boolean Generate print variants
state string Generate pseudo-class variants (e.g., hover)
css-var boolean Output as CSS custom property instead of property
css-variable-name string Override the CSS variable name
local-vars map Additional local CSS variables

Add, modify, or remove utilities by manipulating the $utilities map after Bootstrap's default import.

3.11 Component Default Configs (JS)

These are the default configuration objects for JavaScript-driven components. Override via data-bs-* attributes or the JS constructor's config parameter.

Carousel:

Option Type Default Description
interval number 5000 Auto-cycling delay in ms
keyboard boolean true React to keyboard events
pause string/false 'hover' Pause on mouseenter
ride string/false false Auto-start cycling
touch boolean true Enable touch swipe
wrap boolean true Continuous cycling

Collapse:

Option Type Default Description
parent string/element/false null Accordion parent selector
toggle boolean true Toggle on initialization

Dropdown:

Option Type Default Description
autoClose boolean/string true Close behavior
boundary string/element 'clippingParents' Overflow boundary for Popper
display string 'dynamic' Popper positioning ('dynamic' or 'static')
offset array/function [0, 2] [skidding, distance]
popperConfig object/function/null null Custom Popper config
reference string/element/object 'toggle' Reference element for Popper

Modal:

Option Type Default Description
backdrop boolean/string true Include backdrop ('static' prevents close on click)
focus boolean true Focus modal on open
keyboard boolean true Close on Escape key

Offcanvas:

Option Type Default Description
backdrop boolean true Show backdrop
keyboard boolean true Close on Escape key
scroll boolean false Allow body scrolling while open

Backdrop Utility:

Option Type Default
className string 'modal-backdrop'
clickCallback function/null null
isAnimated boolean false
isVisible boolean true
rootElement string/element 'body'

FocusTrap Utility:

Option Type Default
autofocus boolean true
trapElement element/null null

4. Deployment & Scaling

4.1 CDN Deployment

The fastest path to production. Include the prebuilt CSS and JS from a CDN (jsDelivr, cdnjs, unpkg):

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>

Use SRI (Subresource Integrity) hashes for security — see Section 7.3.

4.2 Self-Hosting

Copy the dist/ directory contents to your static asset server. The dist/ contains:

dist/
├── css/
│   ├── bootstrap.css          (+ .map)
│   ├── bootstrap.min.css      (+ .map)
│   ├── bootstrap.rtl.css      (+ .map)
│   ├── bootstrap.rtl.min.css  (+ .map)
│   ├── bootstrap-grid.css     (+ .min.css variants)
│   ├── bootstrap-reboot.css   (+ .min.css variants)
│   └── bootstrap-utilities.css (+ .min.css variants)
└── js/
    ├── bootstrap.js           (+ .map)
    ├── bootstrap.min.js       (+ .map)
    ├── bootstrap.esm.js       (+ .map)
    ├── bootstrap.esm.min.js   (+ .map)
    ├── bootstrap.bundle.js    (+ .map, includes Popper)
    └── bootstrap.bundle.min.js (+ .map, includes Popper)

4.3 Package Manager Integration

npm:

npm install bootstrap@5.3.8

Key fields in package.json:

Field Value Purpose
main dist/js/bootstrap.js CommonJS/UMD entry
module dist/js/bootstrap.esm.js ES module entry
sass scss/bootstrap.scss Sass entry
style dist/css/bootstrap.css Pre-compiled CSS

Published files include dist/{css,js}/*.{css,js,map}, js/{src,dist}/**/*.{js,map}, js/index.{esm,umd}.js, and scss/**/*.scss (excluding scss/tests).

Composer (PHP):

composer require twbs/bootstrap:5.3.8

Package name: twbs/bootstrap

NuGet (.NET):

Two packages available:

  • bootstrap — compiled CSS and JS
  • bootstrap.sass — Sass source files

Meteor.js:

meteor add twbs:bootstrap

4.4 Subset Builds

Bootstrap provides focused subsets for minimal footprints:

Subset Entry File Purpose Max Gzipped Size
Grid only scss/bootstrap-grid.scss Grid + flexbox utilities 6.0 kB
Reboot only scss/bootstrap-reboot.scss Normalize + reboot 3.25 kB
Utilities only scss/bootstrap-utilities.scss All utility classes 10.75 kB

4.5 Custom Sass Builds

Create a custom entry file that imports only what you need:

// custom.scss — import only needed components
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/root";
@import "bootstrap/scss/reboot";

// Only the components you use:
@import "bootstrap/scss/grid";
@import "bootstrap/scss/buttons";
@import "bootstrap/scss/forms";
@import "bootstrap/scss/utilities";
@import "bootstrap/scss/utilities/api"; // Must be last — generates utility classes

4.6 Production Optimization

Tip

For production builds, combine a custom Sass import with PurgeCSS (or your bundler's tree-shaking) to eliminate unused CSS. Bootstrap's full minified CSS is 30.25 kB gzipped — a selective import plus PurgeCSS can reduce this to under 10 kB for typical projects.

Bundle size budget:

File Max Gzipped Size
bootstrap.min.css 30.25 kB
bootstrap.min.js 16.25 kB
bootstrap.bundle.min.js 23.5 kB
bootstrap.esm.min.js 18.25 kB
bootstrap-grid.min.css 6.0 kB
bootstrap-reboot.min.css 3.25 kB
bootstrap-utilities.min.css 10.75 kB

5. Operations

5.1 Build System — npm Scripts Reference

All build orchestration runs through npm scripts defined in package.json.

Top-Level Commands

Command Description
npm start Run parallel watchers + docs site dev server
npm run dist Build CSS and JS in parallel (production)
npm test Full test suite: lint + dist + JS tests + docs build + docs lint
npm run release Full release: dist + SRI hashes + docs build + zip
npm run lint Run all linters (JS + CSS + lockfile)
npm run watch Parallel watchers for CSS (main, dist, docs, test) and JS (main, docs)

CSS Commands

Command Description
npm run css Full CSS pipeline: compile + prefix + RTL + minify
npm run css-compile sass --style expanded --source-map --embed-sources --no-error-css scss/:dist/css/
npm run css-rtl Generate RTL variants via PostCSS with RTLCSS
npm run css-lint Stylelint + find-unused-sass-variables
npm run css-test Sass unit tests via jasmine --config=scss/tests/jasmine.js
npm run css-minify Minify CSS output with clean-css

JS Commands

Command Description
npm run js Full JS pipeline: compile + minify
npm run js-compile Rollup builds (standalone, standalone-esm, bundle, plugins)
npm run js-lint ESLint
npm run js-test Karma tests + jQuery integration tests + integration tests
npm run js-debug Run Karma tests with DEBUG=true
npm run js-minify Minify JS output with Terser

Docs Commands

Command Description
npm run docs Build docs + lint
npm run docs-build astro build --root site
npm run docs-serve astro dev --root site --port 9001

5.2 Watch Mode

npm run watch starts six parallel watchers:

  • css-main — recompiles main SCSS on changes
  • css-dist — recompiles distribution CSS
  • css-docs — recompiles docs-specific CSS
  • css-test — reruns SCSS tests
  • js-main — rebuilds main JS bundle
  • js-docs — rebuilds docs JS

npm start combines watch mode with docs-serve for a full local development environment at http://localhost:9001.

5.3 Docs Site Local Development

The documentation site is built with Astro 5.18.1 as a static site generator:

# Install dependencies
npm install

# Start docs dev server on port 9001
npm run docs-serve

# Build static docs site
npm run docs-build

The site source lives under site/:

Directory Content
site/astro.config.ts Astro configuration
site/data/*.yml Data files (breakpoints, colors, team, versions, sidebar, etc.)
site/src/content/docs/ MDX documentation pages
site/src/components/ Astro components (shortcodes, header, footer, icons)
site/src/layouts/ Page layouts (Base, Docs, Examples, Redirect, Single)
site/src/libs/ TypeScript utilities (config, content, data, toc, prism, etc.)
site/src/pages/ Astro route pages

Site configuration values from config.yml:

Key Value
current_version 5.3.8
docs_version 5.3
rfs_version v10.0.0
algolia.app_id AK7KMZKZHQ
algolia.index bootstrap
analytics.fathom ITUSEYJG

5.4 Release Process

The npm run release script executes:

  1. npm run dist — build all CSS and JS
  2. release-sri — generate Subresource Integrity hashes
  3. npm run docs-build — build the documentation site
  4. release-zip — package distribution files into a zip archive

6. Performance

6.1 Bundle Size Analysis

Bootstrap's distribution files are size-checked as part of the build process:

File Max Gzipped Size
bootstrap.min.css 30.25 kB
bootstrap.min.js 16.25 kB
bootstrap.bundle.min.js (includes Popper) 23.5 kB
bootstrap.esm.min.js 18.25 kB
bootstrap-grid.min.css 6.0 kB
bootstrap-reboot.min.css 3.25 kB
bootstrap-utilities.min.css 10.75 kB

6.2 Tree-Shaking Individual JS Components

The ES module entry (js/index.esm.js) exports all 12 plugin components individually. Modern bundlers (Webpack 4+, Rollup, Vite) can tree-shake unused exports:

// Only imports Tooltip and Modal — bundler eliminates the rest
import { Tooltip, Modal } from 'bootstrap';

For maximum control, import directly from source:

import Tooltip from 'bootstrap/js/src/tooltip';
import Modal from 'bootstrap/js/src/modal';

6.3 CSS Optimization with PurgeCSS

Bootstrap generates utility classes for every value in every configured map. Most projects use a fraction of these. Integrate PurgeCSS (or Tailwind CSS's JIT-like approach) into your build pipeline:

// postcss.config.js example
module.exports = {
  plugins: [
    require('@fullhuman/postcss-purgecss')({
      content: ['./src/**/*.html', './src/**/*.js'],
      safelist: {
        // Keep dynamically-added classes
        greedy: [/^modal/, /^tooltip/, /^popover/, /^offcanvas/]
      }
    })
  ]
};

Caution

PurgeCSS can remove classes that are added dynamically by JavaScript components (e.g., modal-backdrop, show, fade, collapsing). Always safelist class patterns for any Bootstrap JS component you use.

6.4 RFS (Responsive Font Sizes)

Bootstrap uses RFS v10.0.0 to scale font sizes and spacing values responsively. RFS converts px or rem values into a calc() expression that scales between a minimum and maximum viewport width. This is applied automatically to heading sizes and can be enabled for any utility via the rfs: true flag in the utilities API.

6.5 Import Strategies

Strategy CSS Size Impact JS Size Impact Best For
Full CDN 30.25 kB CSS + 23.5 kB JS None Prototyping, small sites
Custom Sass imports 40-80% reduction N/A Production sites with build step
Custom Sass + PurgeCSS 70-95% reduction N/A Performance-critical sites
ES module tree-shaking N/A 30-70% reduction SPAs, apps using few components
Subset builds (grid/reboot/utilities) 80-90% reduction N/A Utility-focused projects

7. Security

7.1 HTML Sanitizer (Tooltip & Popover)

Bootstrap includes a built-in HTML sanitizer (js/src/util/sanitizer.js) that filters content passed to Tooltip and Popover components. This prevents XSS attacks when content is sourced from user input or untrusted data.

The sanitizer maintains an allowlist of safe HTML elements and attributes. Content not matching the allowlist is stripped before insertion into the DOM.

Warning

The built-in sanitizer provides defense-in-depth but should not be your only XSS prevention layer. Always sanitize user input server-side before it reaches the client. If you pass content via the html: true option and a custom sanitizeFn, ensure your custom function is at least as strict as the default.

7.2 XSS Prevention Patterns

  • Data attributes: Values read from data-bs-* attributes are treated as configuration, not raw HTML. The Manipulator module (js/src/dom/manipulator.js) handles type coercion.
  • Template rendering: The TemplateFactory (js/src/util/template-factory.js) used by Tooltip and Popover sanitizes HTML content before DOM insertion.
  • Event system: Bootstrap's custom event system (js/src/dom/event-handler.js) does not evaluate string content as code.

7.3 Subresource Integrity (SRI)

When loading Bootstrap from a CDN, use SRI hashes to ensure the file has not been tampered with:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-HASH_HERE"
      crossorigin="anonymous">

SRI hashes are generated during the release process (release-sri npm script) and published on the Bootstrap website.

7.4 Content Security Policy Considerations

Bootstrap's CSS uses inline styles for certain dynamic operations (e.g., Carousel slide positioning, progress bar widths). If your CSP disallows style-src 'unsafe-inline', you will need to either:

  • Use a nonce-based CSP and inject the nonce into Bootstrap's style operations
  • Use CSS custom properties for dynamic values instead of inline styles
  • Whitelist specific hashes for Bootstrap's known inline style patterns

Bootstrap's JavaScript does not use eval() or new Function(), so script-src 'unsafe-eval' is not required.


8. Developer Internals

8.1 Repository Structure

twbs/bootstrap/                     (657 files, 284,276 source chars)
├── js/
│   ├── index.esm.js               ES module entry (exports all 12 plugins)
│   ├── index.umd.js               UMD entry (exports as `bootstrap` global)
│   └── src/
│       ├── alert.js               Alert plugin
│       ├── base-component.js      BaseComponent (VERSION = '5.3.8')
│       ├── button.js              Button plugin
│       ├── carousel.js            Carousel plugin
│       ├── collapse.js            Collapse plugin
│       ├── dropdown.js            Dropdown plugin (uses Popper)
│       ├── modal.js               Modal plugin
│       ├── offcanvas.js           Offcanvas plugin
│       ├── popover.js             Popover plugin (extends Tooltip)
│       ├── scrollspy.js           ScrollSpy plugin
│       ├── tab.js                 Tab plugin
│       ├── toast.js               Toast plugin
│       ├── tooltip.js             Tooltip plugin (uses Popper)
│       ├── dom/                   DOM abstraction layer
│       │   ├── data.js            Per-element data storage (Map-based)
│       │   ├── event-handler.js   Event system (namespacing, delegation)
│       │   ├── manipulator.js     Data-attribute reading/writing
│       │   └── selector-engine.js querySelector wrappers
│       └── util/                  Utility modules
│           ├── index.js           Common utility functions
│           ├── config.js          Config base class
│           ├── backdrop.js        Backdrop class
│           ├── component-functions.js  enableDismissTrigger
│           ├── focustrap.js       FocusTrap class
│           ├── sanitizer.js       HTML sanitizer
│           ├── scrollbar.js       ScrollBarHelper
│           ├── swipe.js           Touch swipe detection
│           └── template-factory.js Template rendering
├── scss/
│   ├── bootstrap.scss             Main entry
│   ├── bootstrap-grid.scss        Grid-only subset
│   ├── bootstrap-reboot.scss      Reboot-only subset
│   ├── bootstrap-utilities.scss   Utilities-only subset
│   ├── _variables.scss            All Sass variables
│   ├── _variables-dark.scss       Dark mode variable overrides
│   ├── _maps.scss                 Sass map finalization
│   ├── _mixins.scss               Mixin imports
│   ├── _functions.scss            Sass functions
│   ├── _root.scss                 CSS custom properties
│   ├── _reboot.scss               Normalize/reboot
│   ├── _utilities.scss            Utility definitions
│   ├── forms/                     Form component partials (8 files)
│   ├── helpers/                   Helper partials (12 files)
│   ├── mixins/                    Mixin partials (24 files)
│   ├── utilities/
│   │   └── _api.scss              Utility class generator
│   └── tests/                     Sass unit tests
├── site/                          Astro docs site
│   ├── astro.config.ts
│   ├── data/                      YAML data files
│   ├── src/
│   │   ├── content/docs/          MDX documentation
│   │   ├── components/            Astro components
│   │   ├── layouts/               Page layouts
│   │   ├── libs/                  TypeScript utilities
│   │   └── pages/                 Route pages
├── build/                         Build scripts (Rollup, plugins)
├── dist/                          Compiled output (CSS + JS)
└── nuget/                         NuGet package specs

8.2 Class Hierarchy Deep Dive

Config Base Class (js/src/util/config.js)

Every configurable component extends Config. It provides:

  • static get Default — returns the default config object
  • static get DefaultType — returns type constraints (used for validation)
  • static get NAME — component name (must be implemented by subclasses; throws Error: You have to implement the static method "NAME" if missing)
  • _mergeConfigObj(config, element) — merges config from multiple sources
  • _typeCheckConfig(config) — validates each config key against DefaultType

Configuration Merge Pipeline

The _mergeConfigObj method resolves the final configuration through a 4-layer override chain:

Layer 1: Static Default object (lowest priority)
    ↓
Layer 2: data-bs-config='{"key": "value"}' JSON attribute on the element
    ↓
Layer 3: Individual data-bs-{key} attributes on the element
    ↓
Layer 4: JavaScript config object passed to constructor (highest priority)

Note

The data-bs-config JSON attribute provides a way to set multiple options in a single attribute. Individual data-bs-* attributes override keys from data-bs-config. The JS constructor config overrides everything.

BaseComponent (js/src/base-component.js)

Extends Config. Every visible plugin extends BaseComponent, which provides:

  • Constructor: stores the component instance in the DOM data store (data.js) keyed by element + component name
  • dispose() — removes event listeners and clears stored data
  • static getInstance(element) — retrieves existing instance from data store
  • static getOrCreateInstance(element, config) — get or create with lazy init
  • static get VERSION — returns '5.3.8'

Plugin Pattern

Each plugin follows a consistent structure:

class ComponentName extends BaseComponent {
  static get Default() { return { /* ... */ } }
  static get DefaultType() { return { /* ... */ } }
  static get NAME() { return 'componentName' }

  // Public API
  show() { /* ... */ }
  hide() { /* ... */ }
  toggle() { /* ... */ }
  dispose() { /* ... */ }

  // Private implementation
  _method() { /* ... */ }

  // Static: jQuery interface + data-api event binding
  static jQueryInterface(config) { /* ... */ }
}

8.3 DOM Layer

data.js — Per-Element Data Storage

Uses a Map keyed by DOM element to store component instances. This replaces jQuery's .data() method with a framework-agnostic approach. Each element can hold one instance per component type.

event-handler.js — Custom Event System

Features:

  • Namespacing: events are namespaced as {event}.bs.{component} (e.g., show.bs.modal, hidden.bs.collapse)
  • Event delegation: supports delegated event listeners via selector parameter
  • One-off listeners: one() method for single-execution handlers
  • Custom events: Bootstrap fires custom events that are cancelable — calling event.preventDefault() on show or hide events stops the operation

Standard event lifecycle for visibility-toggling components:

Event When Fired Cancelable
show.bs.{component} Before showing Yes
shown.bs.{component} After shown (transition complete) No
hide.bs.{component} Before hiding Yes
hidden.bs.{component} After hidden (transition complete) No

Additional component-specific events:

  • Modal: hidePrevented.bs.modal (when static backdrop prevents close)
  • Carousel: slide.bs.carousel, slid.bs.carousel

manipulator.js — Data Attribute Reading

Reads and writes data-bs-* attributes with automatic type coercion (strings "true"/"false" become booleans, numeric strings become numbers).

selector-engine.js — Query Wrappers

Provides querySelector and querySelectorAll wrappers, plus getElementFromSelector() which resolves the target element from data-bs-target or href attributes.

8.4 Utility Layer

index.js — Common Utilities

Key exported functions:

Function Purpose
parseSelector Parse and escape selector strings
toType Reliable type checking (replaces typeof)
getUID Generate unique IDs
getTransitionDurationFromElement Read CSS transition duration
triggerTransitionEnd Force transition end dispatch
isElement Check if value is a DOM element
getElement Resolve selector string to element
isVisible Check element visibility
isDisabled Check disabled state
findShadowRoot Find shadow DOM root
noop No-operation function
reflow Force browser reflow
getjQuery Detect jQuery presence
onDOMContentLoaded Safe DOMContentLoaded handler
isRTL Check dir="rtl" on <html>
defineJQueryPlugin Register plugin with jQuery
execute Execute function or return value
executeAfterTransition Run callback after CSS transition
getNextActiveElement Cycle through element list

backdrop.js

Manages the semi-transparent overlay for Modal and Offcanvas. Config: className, clickCallback, isAnimated, isVisible, rootElement.

focustrap.js

Traps keyboard focus within Modal and Offcanvas containers. Listens for focusin events and redirects focus back to the trap element when focus escapes. Config: autofocus, trapElement.

sanitizer.js

Provides HTML sanitization for Tooltip and Popover content. Maintains an allowlist of safe elements and attributes. Custom sanitizer functions can be provided via the sanitizeFn config option.

scrollbar.js

ScrollBarHelper handles hiding and restoring the browser scrollbar when Modal or Offcanvas opens. Calculates scrollbar width and applies compensating padding to prevent layout shift.

swipe.js

Touch event detection for Carousel. Detects horizontal swipe gestures and translates them into next/previous slide actions.

template-factory.js

Renders HTML templates for Tooltip and Popover. Handles content injection, sanitization, and class application.

component-functions.js

Exports enableDismissTrigger() — wires up [data-bs-dismiss="{component}"] buttons to call close() or hide() on the parent component. Used by Alert, Toast, Modal, and Offcanvas.

8.5 SCSS Architecture

Import Order

The main entry (scss/bootstrap.scss) imports partials in a specific, dependency-respecting order:

  1. _functions.scss — Sass functions (must be first)
  2. _variables.scss — All variable definitions
  3. _variables-dark.scss — Dark mode overrides
  4. _maps.scss — Map finalization and merging
  5. _mixins.scss — All mixin imports
  6. _root.scss — CSS custom properties on :root
  7. _reboot.scss — Normalize + base styles
  8. Component partials (type, images, containers, grid, tables, forms, buttons, etc.)
  9. _helpers.scss — Helper classes
  10. _utilities.scss + utilities/_api.scss — Utility class generation (must be last)

Important

When creating custom builds, maintain this import order. Functions and variables must precede mixins, which must precede components. The utilities API must be imported last because it reads the finalized $utilities map to generate classes.

Mixins Directory (24 mixins)

Mixin Purpose
_alert.scss Alert variant generator
_backdrop.scss Backdrop styles
_banner.scss Banner styles
_border-radius.scss Border radius utilities
_box-shadow.scss Box shadow utilities
_breakpoints.scss Media query helpers (media-breakpoint-up, -down, -between, -only)
_buttons.scss Button variant generator
_caret.scss Dropdown caret styles
_clearfix.scss Clearfix
_color-mode.scss Color mode selector generation
_color-scheme.scss Color scheme utilities
_container.scss Container generator
_deprecate.scss Deprecation warning helper
_forms.scss Form variant generators
_gradients.scss Gradient backgrounds
_grid.scss Grid system (rows, columns)
_image.scss Responsive image
_list-group.scss List group variant generator
_lists.scss List utilities
_pagination.scss Pagination sizing
_reset-text.scss Text reset
_resize.scss Resize utility
_table-variants.scss Table color variants
_text-truncate.scss Text truncation
_transition.scss Transition helpers
_utilities.scss Utility generation engine
_visually-hidden.scss Screen-reader-only

Forms Directory (8 files)

_floating-labels.scss, _form-check.scss, _form-control.scss, _form-range.scss, _form-select.scss, _form-text.scss, _input-group.scss, _labels.scss, _validation.scss

Helpers Directory (12 files)

_clearfix.scss, _color-bg.scss, _colored-links.scss, _focus-ring.scss, _icon-link.scss, _position.scss, _ratio.scss, _stacks.scss, _stretched-link.scss, _text-truncation.scss, _visually-hidden.scss, _vr.scss

8.6 Event System Architecture

Bootstrap's event system is a complete abstraction over native DOM events:

User Action / JS Call
    ↓
EventHandler.trigger(element, 'show.bs.modal')
    ↓
Create native CustomEvent with:
  - Namespaced type: 'show.bs.modal'
  - cancelable: true (for show/hide)
  - detail: { delegateTarget: element }
    ↓
element.dispatchEvent(event)
    ↓
Registered handlers execute
    ↓
If event.defaultPrevented → operation canceled
If not → proceed with show/hide logic
    ↓
EventHandler.trigger(element, 'shown.bs.modal')

8.7 Error Messages Reference

These are the error messages thrown by Bootstrap's JavaScript components:

Error Source Cause
TypeError: No method named "${config}" All plugins Calling a nonexistent method via jQuery or data API
TypeError: Bootstrap's dropdowns require Popper Dropdown Popper.js not loaded when using standalone build
Error: Please use show on visible elements Tooltip Calling show() on a hidden or detached element
TypeError: DROPDOWN: Option "reference" provided type "object" without a required "getBoundingClientRect" method Dropdown Invalid reference element
Error: You have to implement the static method "NAME" Config Subclass missing required static get NAME()

8.8 Testing Strategy

JavaScript Tests

  • Framework: Jasmine + Karma
  • Browser: Chrome (local), BrowserStack (cloud CI)
  • Coverage target: 90%
  • Test location: js/tests/unit/*.spec.js
  • Visual tests: js/tests/visual/*.html
  • Integration tests: js/tests/integration/
  • Run: npm run js-test
  • Debug mode: npm run js-debug (sets DEBUG=true)

SCSS Tests

  • Framework: sass-true + Jasmine
  • Test location: scss/tests/
  • Run: npm run css-test (invokes jasmine --config=scss/tests/jasmine.js)

Linting

Tool Target Command
ESLint (xo + import + unicorn) JavaScript npm run js-lint
Stylelint (twbs-bootstrap config) SCSS npm run css-lint
find-unused-sass-variables SCSS (part of css-lint)
Prettier Docs site files —
lockfile-lint package-lock.json (part of lint)
vnu-jar HTML HTML validation

8.9 Code Patterns and Conventions

  • Data attribute prefix: All Bootstrap data attributes use the data-bs- prefix
  • Event naming: {event}.bs.{component} (e.g., show.bs.modal)
  • Private methods: Prefixed with underscore (_doSomething())
  • Static interface: Every plugin exposes jQueryInterface, getInstance, getOrCreateInstance
  • Config pattern: Default + DefaultType static getters on every configurable class
  • Disposal: Every component implements dispose() for cleanup
  • jQuery noConflict: Each plugin supports $.fn[name].noConflict()

9. Integration Points

9.1 jQuery Compatibility

Bootstrap auto-detects jQuery via window.jQuery at load time. When detected:

  • Each plugin registers as $.fn[name] (e.g., $('#myModal').modal('show'))
  • The jQueryInterface static method handles jQuery-style method calls
  • $.fn[name].Constructor exposes the plugin class
  • $.fn[name].noConflict() restores previous jQuery plugin binding

To disable jQuery detection, add data-bs-no-jquery to the <body> element.

9.2 Popper.js Integration

Three components depend on @popperjs/core ^2.11.8:

Component Popper Usage
Dropdown Menu positioning relative to toggle
Tooltip Tooltip positioning relative to trigger
Popover Inherits Tooltip positioning

Bundle build (bootstrap.bundle.js/.min.js) includes Popper — no separate import needed.

Standalone build (bootstrap.js/.esm.js) requires Popper loaded separately. If missing, Dropdown throws TypeError: Bootstrap's dropdowns require Popper.

Custom Popper configuration can be passed via the popperConfig option (object or function returning an object).

9.3 Bundler Integration

Webpack

// webpack.config.js
module.exports = {
  resolve: {
    // Use the ESM build for tree-shaking
    mainFields: ['module', 'main']
  }
};
// Import only what you need
import { Modal, Tooltip } from 'bootstrap';

For Sass integration, configure sass-loader to resolve Bootstrap's SCSS:

// webpack.config.js
{
  loader: 'sass-loader',
  options: {
    sassOptions: {
      // Bootstrap SCSS resolves via node_modules
    }
  }
}

Vite

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

export default {
  css: {
    preprocessorOptions: {
      scss: {
        // Custom variable overrides
        additionalData: `@import "./src/custom-variables";`
      }
    }
  }
};
// main.js — tree-shakeable imports
import { Dropdown, Modal } from 'bootstrap';

Parcel

Parcel resolves Bootstrap automatically from node_modules. Import SCSS directly:

// styles.scss
@import "bootstrap/scss/bootstrap";

Rollup

Bootstrap itself uses Rollup for its builds. For consuming projects:

// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';

export default {
  plugins: [resolve()]
};

9.4 Framework Integration

React

Bootstrap CSS can be imported directly. For JS components, use the imperative API rather than data attributes:

import { Modal } from 'bootstrap';
import { useEffect, useRef } from 'react';

function MyModal({ show, onHide }) {
  const modalRef = useRef(null);
  const bsModal = useRef(null);

  useEffect(() => {
    bsModal.current = new Modal(modalRef.current);
    modalRef.current.addEventListener('hidden.bs.modal', onHide);
    return () => bsModal.current.dispose();
  }, []);

  useEffect(() => {
    if (show) bsModal.current.show();
    else bsModal.current.hide();
  }, [show]);

  return <div ref={modalRef} className="modal fade">...</div>;
}

Tip

For React projects, consider libraries like react-bootstrap or reactstrap that provide React-native component wrappers. If using Bootstrap's JS directly, always call dispose() in cleanup effects to prevent memory leaks.

Vue

Similar to React — import CSS globally and use the imperative JS API in lifecycle hooks:

import { Modal } from 'bootstrap';

export default {
  mounted() {
    this.bsModal = new Modal(this.$refs.modal);
    this.$refs.modal.addEventListener('hidden.bs.modal', this.onHide);
  },
  beforeUnmount() {
    this.bsModal.dispose();
  }
};

9.5 Astro Docs Site Architecture

The Bootstrap documentation site is itself a substantial Astro application:

Layer Technology
Framework Astro 5.18.1 (static site generation)
Content MDX files in site/src/content/docs/
Syntax highlighting Prism
Markdown processing rehype + remark plugins
Data YAML files in site/data/
Search Algolia (app ID: AK7KMZKZHQ, index: bootstrap)
Analytics Fathom (ITUSEYJG)

The docs site uses two environment-only configuration values (NODE_ENV and DEPLOY_PRIME_URL) for build-time behavior — these are not user-facing configuration.

9.6 Known Open Issues

Issue Description
#41925 Popover data-bs-content="true"/"false" auto-converted to boolean, causing TypeError
#42328 Missing aria-pressed="false" at toggle button initialization
#40962 dart-sass 1.80.0+ deprecation warnings
#39984 Dark dropdowns/navbars don't receive dark variables with dark theme
#37807 Grid system should support CSS Container Queries
#41192 Variable for subtract .02px
#33761 Alert JS closing event name doesn't fit naming conventions
#29378 Expounding on "opt-in for performance reasons"

Note

Issue #41925 is a practical trap: setting data-bs-content="true" or data-bs-content="false" on a Popover results in the string being coerced to a boolean by the Manipulator module, which then causes a TypeError. Use different string values or set content via JavaScript to avoid this.