Every utility class comes from one entry in the $utilities map (Under the Hood). Change the map between the utilities and utilities/api imports and the generated classes change with it; one map-merge() can add, modify and remove entries at once.
@import "bootstrap/scss/functions", "bootstrap/scss/variables", "bootstrap/scss/variables-dark",
"bootstrap/scss/maps", "bootstrap/scss/mixins", "bootstrap/scss/utilities";
$utilities: map-merge($utilities, (
"measure": ( // add: .measure-prose, .measure-md-wide ...
property: max-width,
class: measure,
responsive: true,
values: (prose: 65ch, wide: 80ch),
),
"shadow": map-merge(map-get($utilities, "shadow"), (state: hover)), // modify
"float": null, // remove every .float-* class
));
@import "bootstrap/scss/utilities/api";npx sass --load-path=node_modules --no-source-map --silence-deprecation=import,global-builtin,\
color-functions,if-function src/utilities.scss out.css
grep -A2 "measure-md-prose\|shadow-lg-hover" out.css; grep -c "float" out.cssOutput
.shadow-lg-hover:hover {
box-shadow: var(--bs-box-shadow-lg) !important;
}
--
.measure-md-prose {
max-width: 65ch !important;
}
0A responsive: true entry is printed once plain and again inside each of the five breakpoint media queries, so the two measure values become 12 classes. That multiplication is why bootstrap-utilities.min.css alone weighs 85 kB: enable responsive only where you need it and remove groups you never use. Other options are state (pseudo-classes), print, rtl: false and css-var: true, which sets a custom property instead of a declaration.