Migration

Migrating from Bootstrap

Move Bootstrap-styled screens toward Master CSS while preserving vendor CSS, JavaScript-driven components, and cascade-dependent overrides.

Bootstrap and Master CSS can run side by side. Keep Bootstrap loaded while existing markup still depends on its grid, utilities, components, JavaScript behavior, Sass variables, or selector overrides. Convert one screen or component family at a time, then remove Bootstrap only after the product no longer relies on it.

This guide focuses on app-owned Bootstrap usage. Vendor markup, third-party plugins, generated HTML, and Bootstrap JavaScript components can stay on Bootstrap until the project has a deliberate replacement.


Migration strategy

Start with coexistence.

  1. Import Master CSS from the app stylesheet without removing Bootstrap.
  2. Keep Bootstrap CSS, Sass output, and JavaScript imports while current screens depend on them.
  3. Audit Bootstrap utilities, grid classes, components, Sass variable overrides, and custom selectors.
  4. Move project-owned design values into Master CSS @theme.
  5. Convert layout wrappers, spacing, typography, and simple surfaces to Master CSS classes.
  6. Keep Bootstrap JavaScript components and data attributes until equivalent behavior exists.
  7. Remove Bootstrap packages only after validation proves no converted path needs them.

The first milestone is a stable app where both systems load and new Master CSS classes work. Dependency removal is the last step, not the first.


Audit checklist

Inspect the Bootstrap surface before changing files.

AreaWhat to look forMigration decision
CSS entrybootstrap/dist/css/bootstrap.css, compiled Sass output, and app CSS import orderAdd Master CSS beside the existing entry and preserve cascade order during migration.
Sass setup$theme-colors, $spacers, $grid-breakpoints, $container-max-widths, and partial importsMove product-owned values into @theme; keep Bootstrap variables needed by remaining Bootstrap components.
Grid and layout.container, .row, .col-*, .g-*, display, flex, and spacing utilitiesConvert app-owned layout wrappers to Master CSS classes.
ComponentsButtons, navs, modals, dropdowns, accordions, alerts, forms, and cardsConvert simple visual surfaces first; keep behavior-heavy components on Bootstrap.
JavaScript behaviordata-bs-*, Bootstrap plugin imports, portals, focus handling, transitions, and eventsKeep until a replacement interaction is implemented and tested.
OverridesSelectors that target Bootstrap classes, component states, or generated markupKeep as CSS until the underlying component is migrated.

Add Master CSS beside Bootstrap

Import Master CSS from the stylesheet your app already loads. Do not remove Bootstrap imports yet.

@import "bootstrap/dist/css/bootstrap.css";@import "@master/css";

Default source discovery is enough for ordinary app files. Add explicit source directives only when the app needs custom include, exclude, safelist, or blocklist behavior.

If Bootstrap should stay lower in the cascade, keep its import before Master CSS or wrap vendor CSS in a lower-priority layer controlled by the project. Verify the resulting cascade in the browser before deleting any overrides.


Move Bootstrap Sass values into @theme

Bootstrap Sass variables often contain product decisions. Move those decisions into Master CSS tokens when they should be used by markup outside Bootstrap components.

$primary: #2563eb;$body-color: #172033;$border-radius: .5rem;$spacer: 1rem;
@import "@master/css";@theme {    --color-primary: #2563eb;    --color-body: #172033;    --radius-control: .5rem;    --spacing-page: 1rem;}
<section class="fg:body p:page r:control bg:white">    ...</section>

Do not assume Bootstrap's scale names match the Master CSS preset. Move the values that matter to the product, then choose Master CSS token names that describe their role.


Convert grid and utility classes

Start with layout wrappers and simple utility-only markup.

Instead of preserving Bootstrap class spelling, preserve layout intent:

<!-- Before: container py-5 --><!-- Before: row g-4 --><!-- Before: col-md-4 -->
<section class="w:full max-w:6xl mx:auto px:md py:2xl">    <div class="grid grid-cols:3@md gap:lg">        <article class="p:lg r:lg bg:white b:1px|solid|base">            ...        </article>    </div></section>

Use native declaration syntax when it is clearer than a utility alias:

<div class="display:contents@md scroll-margin-top:4rem">    ...</div>

Keep Bootstrap layout classes in templates that still need Bootstrap's container widths, gutter assumptions, or component internals.


Convert simple components

Buttons, cards, alerts, and badges are often app-owned visual patterns. Convert them to markup classes or Master CSS component classes when the project owns the behavior.

@import "@master/css";@components {    btn-primary {        @compose inline-flex align-items:center justify-content:center gap:xs px:md h:10x r:control bg:primary fg:white;        @compose bg:blue-70:hover opacity:.5:disabled;    }    panel {        @compose bg:white fg:body r:lg b:1px|solid|base p:lg shadow:sm;    }}
<button class="btn-primary">Save</button><article class="panel">...</article>

Keep Bootstrap components when they still provide behavior, accessibility, or internal structure, such as dropdowns, modals, tabs, carousels, and collapse regions. You can still add a small Master CSS class to a Bootstrap root element when the component forwards the class and the cascade is clear.


Preserve JavaScript-driven components

Bootstrap JavaScript components are not just CSS. They can manage focus, ARIA attributes, transitions, body scroll locks, popper positioning, and events.

Keep markup with data-bs-* attributes on Bootstrap until the replacement behavior has been implemented and tested. Convert only the surrounding layout or product-owned wrappers first.

<section class="grid gap:md">    <!-- Bootstrap modal trigger and modal markup can remain unchanged here. --></section>

When a component is replaced, remove its Bootstrap JavaScript import and related data attributes in the same reviewable batch.


Handle overrides and vendor CSS

Many Bootstrap projects rely on selector overrides such as component state classes, nested markup selectors, or specificity fixes. Do not translate those blindly.

Keep the override as CSS when it targets Bootstrap internals:

.navbar .dropdown-menu {    min-width: 16rem;}

Move the override to Master CSS only after the markup is app-owned:

<nav class="flex align-items:center gap:md">    <div class="min-w:64x">...</div></nav>

Vendor CSS and third-party Bootstrap themes should remain regular CSS until the project replaces the vendor contract.


Validate the migration

  • Run the project's formatter, linter, type check, tests, and production build after each batch.
  • Compare pages that used Bootstrap grid, container, form, modal, dropdown, collapse, tooltip, popover, and responsive utilities.
  • Test hover, focus-visible, disabled, expanded, selected, validation, and dark-mode states if the project supports them.
  • Keep Bootstrap loaded until no remaining template, component, plugin, or override depends on it.
  • Remove Bootstrap Sass, CSS, JavaScript imports, and packages only after the full validation suite passes.

Useful references

  • Master UI


© 2026 Aoyue Design LLC.MIT License
Trademark Policy