Bootstrap 6 with Webpack
Set up a Bootstrap 6 project bundled with Webpack, including the loaders needed to process Sass. Requires Node.js and terminal familiarity.
Workflow
- Step 1: Set up npm and install dependencies
- Step 2: Create the project structure
- Step 3: Configure Webpack (boilerplate + dev server)
- Step 4: Set up loaders and import Bootstrap
- Step 5: Verify
- Step 6 (optional): Production optimizations
Step 1: Set up npm and install dependencies
-
Create the project and initialize npm:
mkdir my-project && cd my-project npm init -y -
Install Webpack and its tooling:
npm i --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin -
Install Bootstrap and its optional peer dependencies (omit
@floating-ui/domif not using menus/popovers/tooltips; omitvanilla-calendar-proif not using the datepicker):npm i --save bootstrap@6.0.0-alpha.1 @floating-ui/dom vanilla-calendar-pro -
Install the loaders and Sass/Autoprefixer needed to bundle Bootstrap's CSS:
npm i --save-dev autoprefixer css-loader postcss-loader sass sass-loader style-loader
Step 2: Create the project structure
mkdir {src,src/js,src/scss}
touch src/index.html src/js/main.js src/scss/styles.scss webpack.config.js
Target layout:
my-project/
├── src/
│ ├── js/
│ │ └── main.js
│ ├── scss/
│ │ └── styles.scss
│ └── index.html
├── package-lock.json
├── package.json
└── webpack.config.js
Step 3: Configure Webpack
-
webpack.config.js— entry, output, and dev server:'use strict' const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode: 'development', entry: './src/js/main.js', output: { filename: 'main.js', path: path.resolve(__dirname, 'dist') }, devServer: { static: path.resolve(__dirname, 'dist'), port: 8080, hot: true }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ] } -
src/index.html:<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Bootstrap w/ Webpack</title> </head> <body> <div class="container py-4 px-3 mx-auto"> <h1>Hello, Bootstrap and Webpack!</h1> <button class="btn-solid theme-primary">Primary button</button> </div> </body> </html> -
package.json— add scripts:{ "scripts": { "start": "webpack serve", "build": "webpack build --mode=production", "test": "echo \"Error: no test specified\" && exit 1" } } -
Start Webpack:
npm start
Step 4: Set up loaders and import Bootstrap
-
Add the
module.rulesloader chain towebpack.config.js(order matters:sass-loadercompiles,postcss-loaderruns Autoprefixer,css-loaderresolves imports,style-loaderinjects CSS):'use strict' const path = require('path') const autoprefixer = require('autoprefixer') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode: 'development', entry: './src/js/main.js', output: { filename: 'main.js', path: path.resolve(__dirname, 'dist') }, devServer: { static: path.resolve(__dirname, 'dist'), port: 8080, hot: true }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ], module: { rules: [ { test: /\.(scss)$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'postcss-loader', options: { postcssOptions: { plugins: [ autoprefixer ] } } }, { loader: 'sass-loader' } ] } ] } } -
src/scss/styles.scss— import the source Sass with@use(never@import):// Import all of Bootstrap's CSS @use "bootstrap/scss/bootstrap";To customize, override Bootstrap's CSS token maps (
$root-tokens,$*-tokens) — see Customize › Sass. Token names are written unprefixed in Sass; Bootstrap's dist/CDN CSS adds the--bs-prefix via PostCSS, so compiling the source yourself keeps them unprefixed. -
src/js/main.js— load the CSS and import Bootstrap's JS. Floating UI and Vanilla Calendar Pro are imported automatically through Bootstrap:// Import our custom CSS, then all of Bootstrap’s JS import '../scss/styles.scss' import * as bootstrap from 'bootstrap'Import only the plugins you need to keep bundle sizes down:
import { Tooltip, Toast, Popover } from 'bootstrap'
Step 5: Verify
- Run
npm startand openhttp://localhost:8080— the.containerand.btn-solid.theme-primarybutton should be styled. - Confirm the console is free of module-resolution or loader errors.
- Trigger a JS component (tooltip/dialog) to confirm the JS bundle works.
- Bootstrap 6 requires a browser that supports
oklch()andcolor-mix().
Step 6 (optional): Production optimizations
Not required for a working setup; apply only if needed.
- Extract CSS to a file (for strict CSP or to avoid a large JS bundle): install
mini-css-extract-plugin, replacestyle-loaderwithminiCssExtractPlugin.loader, add the plugin, then link the generateddist/main.cssfrom your HTML. - Extract inline SVGs: Bootstrap's CSS references SVGs via inline
data:URIs. If your CSP blocksdata:images, add a Webpack asset-module rule matchingmimetype: 'image/svg+xml'/scheme: 'data'withtype: 'asset/resource'to emit them as files.
For a complete reference, see the twbs/examples Webpack project.
