Migrating to Bootstrap 5

Suppose TrailMap was built on Bootstrap 4 and it's time to move it to Bootstrap 5. Nearly every Bootstrap-4-specific detail this track flagged along the way — the jQuery dependency, the data-toggle attributes, the ml-/mr- utilities, the .custom-* form controls — has a Bootstrap 5 counterpart. This lesson pulls all of those call-outs together into one reference checklist you can run down line by line. (If you're coming from the other direction, our Bootstrap 5 track has the mirror-image lesson: Migrating from Bootstrap 4.)

Step 1: Remove jQuery/Popper.js, Initialize Components in Vanilla JS

Bootstrap 5 dropped the jQuery dependency this track's Performance lesson called out as unavoidable in Bootstrap 4. Any custom script calling Bootstrap's jQuery plugin API has to be rewritten to construct a real JS class instance instead:

// Bootstrap 4 — jQuery plugin call
$('#trailModal').modal('show');

// Bootstrap 5 — vanilla JS, construct an instance
const trailModal = new bootstrap.Modal(document.getElementById('trailModal'));
trailModal.show();

Step 2: Add the bs- Prefix to Every Data Attribute

Every data-* attribute Bootstrap's own JavaScript reads gained a bs- namespace prefix, to avoid colliding with unrelated libraries reading a plain data-toggle on the same element:

<!-- Bootstrap 4 -->
<button data-toggle="collapse" data-target="#trailNav">...</button>

<!-- Bootstrap 5 -->
<button data-bs-toggle="collapse" data-bs-target="#trailNav">...</button>

Step 3: Renamed Classes Reference Table

Bootstrap 4Bootstrap 5Notes
ml-* / mr-*ms-* / me-*"start"/"end" instead of left/right, for correct RTL layout support
.form-groupPlain .mb-3.form-group was removed outright; a spacing utility on the field wrapper replaces it
.custom-select.form-selectDropped the "custom-" prefix along with the rest of the custom form controls
.custom-control / .custom-checkbox.form-checkCheckboxes and radios unified under one non-"custom" naming scheme
.custom-switch.form-switchSame rename pattern applied to the toggle-switch variant
.badge-pill.rounded-pillPill badges now use the general-purpose rounding utility instead of a badge-only modifier
.font-weight-bold.fw-boldAll font-weight/style utilities were shortened
.sr-only.visually-hiddenSame behavior (hidden visually, present for screen readers), clearer name
.btn-block.d-grid on the parent + .btnFull-width buttons became a grid-layout pattern instead of a dedicated button modifier

Step 4: Components With No Direct Replacement Class

A few Bootstrap-4-only patterns from this track's dedicated lessons don't have a simple rename — they need to be rebuilt:

Bootstrap 4 patternBootstrap 5 approach
JumbotronRemoved outright; rebuild the same look with utility classes (.p-5, .bg-light, .rounded) directly on a plain <div>
Media ObjectRemoved outright; rebuild with flexbox utilities (.d-flex on the wrapper, margin utilities on the image)
Accordion (DIY card + collapse)Becomes a real, dedicated Accordion component with its own documented markup, instead of a card-and-collapse combination you assemble yourself
Note: because Jumbotron and Media Object have no replacement class, these are the two migration steps most likely to be missed in an automated find-and-replace — a script can catch ml-3 → ms-3 mechanically, but "rebuild this component with utilities" needs an actual look at the rendered markup.
Next: every mechanical rename is now on one page. Best Practices Recap closes out the entire Bootstrap 4 track.