Bootstrap 6 2,007 is still unreleased (History and Versions), so everything here comes from the v6-dev branch and its migration guide (github.com/twbs/bootstrap, v6-dev (https://github.com/twbs/bootstrap/blob/v6-dev/site/src/content/docs/guides/migration.mdx 174,933 )), and details can change before release. Check your analytics first: version 6 needs Chrome 1 and Edge 130, Firefox 132 555 and Safari 18 10 , because it relies on light-dark(), :has(), container queries and the native <dialog> element and ships no fallbacks.
Prefixes instead of infixes. Responsive and state variants move to the front of the class name, as in Tailwind CSS 5,202 (Tailwind CSS): d-md-none becomes md:d-none, col-lg-4 becomes lg:col-4, navbar-expand-md becomes md:navbar-expand, and xxl is renamed 2xl. The lg, xl and 2xl breakpoints grow to 1024, 1280 and 1536 px. The demo loads the stylesheet built on the branch on September 12, 2026.
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/twbs/bootstrap@2f488fd/dist/css/bootstrap.min.css">
<div class="row g-5 p-5">
<div class="col-12 sm:col-6"><div class="card"><div class="card-body">
<h5 class="fg-primary">sm:col-6 from 576px</h5>
<p class="md:d-none">This line has md:d-none, so it hides from 768px.</p>
<div><button class="btn-solid theme-primary">Solid</button>
<button class="btn-outline theme-success">Outline</button></div>
</div></div></div>
<div class="col-12 sm:col-6" dir="rtl"><div class="card card-subtle theme-danger">
<div class="card-body border-start border-4 ps-5">
<h5 class="fg-danger">Right to left</h5><p>border-start and ps-5 sit on the right</p>
</div>
</div></div>
</div>
Logical properties and a new scale. Class names such as mt-3, me-2 and border-end stay, but they now set margin-block-start, margin-inline-end and border-inline-end, so one stylesheet serves left-to-right and right-to-left pages (the right column above). The trap: the spacer scale grows from 0-5 to 0-12, so mt-3 is now 0.5rem, not 1rem, and .rounded-* is remapped too. Pages compile but look tighter.
| Area | Bootstrap 5.3 | Bootstrap 6 (preview) |
|---|---|---|
| Color classes | .btn-primary, .text-primary | .btn-solid .theme-primary, .fg-primary |
| Components | Modal, Offcanvas, Dropdown | Dialog (<dialog>), Drawer, Menu |
| Sass 22,539 and colors | @import, $enable-dark-mode, -rgb tokens | @use ... with (...), oklch() |
| JavaScript | UMD, window.bootstrap, Popper 32,753 | ESM only, TypeScript source, Floating UI |
In JavaScript, add type="module" to the <script> tag, import plugins instead of using bootstrap.Tooltip, and rename popperConfig to floatingConfig; show() and hide() now return promises you can await. Class renames are mechanical, so a script can do the first pass.
import { readFileSync } from 'node:fs';
const BREAKPOINTS = new Set(['sm', 'md', 'lg', 'xl', 'xxl']);
const SUFFIXED = new Set(['navbar-expand', 'container', 'table-responsive',
'list-group-horizontal', 'vstack']); // classes whose breakpoint comes last
function toV6(cls) {
const parts = cls.split('-');
const i = parts.findIndex((part, k) => k > 0 && BREAKPOINTS.has(part));
if (i < 0) return cls;
const base = parts.toSpliced(i, 1).join('-');
if (parts[i + 1] ? parts[i + 1] === 'down' : !SUFFIXED.has(base)) return cls; // btn-lg
return `${parts[i] === 'xxl' ? '2xl' : parts[i]}:${base}`;
}
const html = readFileSync(process.argv[2], 'utf8');
console.log(html.replace(/class="([^"]*)"/g,
(_, list) => `class="${list.trim().split(/\s+/).map(toV6).join(' ')}"`));<nav class="navbar lg:navbar-expand"><div class="2xl:container"> <div class="row md:row-cols-3"><button class="btn btn-lg mt-3 lg:d-none">
Run on a file using navbar-expand-lg, container-xxl, row-cols-md-3 and d-lg-none, the script leaves the size class btn-lg alone, but it cannot know that mt-3 shrinks. Build on 5.3.8 for now, prototype v6 on a branch, and after the stable release migrate spacing and component markup by hand, page by page.