CSS is Awesome

Migrating from Bootstrap

If you know Bootstrap, you mostly know css-is-awesome — here's what changes and why.

Why migrate

Bootstrap is a great starting point for a lot of projects, and if yours is humming along, you don't have to move. But the cost of staying shows up in a few familiar places: long theme recompiles, utility markup sprawl, and a JavaScript bundle you may not need. css-is-awesome rethinks those trade-offs.

Philosophy differences

The mental model shifts in four places. Everything else is close enough that muscle memory carries over.

ConcernBootstrapcss-is-awesome
Theming$primary Sass variable + full recompile--ai CSS custom property + hot swap
JS componentsjQuery-era bundle + data-bs-* attributesReact components (or none — plain HTML works)
Utilities.mt-3 .px-4 .d-flex — unprefixed, global.cia-* namespaced, mixin-first
Grid12-column .row .col-md-6Native CSS Grid + flex mixins (@include m.grid(2))

Equivalents table

Day-to-day, these are the substitutions you'll reach for. When both a React component and a mixin are listed, pick whichever layer your project already lives on.

Bootstrapcss-is-awesome
.btn .btn-primary<Button variant="primary"> or @include m.button-primary
.card<Card title="..."> (SCSS component styles live in scss/components/_cards.scss)
.container, .container-fluid@include m.container (default xl) / @include m.container(full)
.row .col-md-6@include m.grid(2) or display: grid; grid-template-columns: 1fr 1fr
.d-flex .justify-content-center .align-items-center.cia-flex-center (or @include m.flex-center)
.mt-3 .px-4.cia-mt-md .cia-px-md (t-shirt scale — see utilities)
.text-primary .bg-lightstyle={{ color: "var(--ai)", background: "var(--surface-subtle)" }} — or a semantic utility
.alert .alert-success<Alert status="success">
.badge .bg-success<Badge status="success">
.modal + data-bs-toggle<Modal> (React, controlled)
.nav .nav-tabs<Tabs> (React)
.form-control, .form-label<Input> + <Label>, or <FormField> for the combined pattern

Side-by-side: button

Same output, two markup styles. Bootstrap first.

<!-- Bootstrap -->
<button type="button" class="btn btn-primary">
  Save changes
</button>
{/* css-is-awesome (React) */}
<Button variant="primary">Save changes</Button>

/* css-is-awesome (SCSS) */
.save-btn {
  @include m.button-primary;
}

Side-by-side: two-column layout

Bootstrap leans on a 12-column abstraction. cia uses CSS Grid directly — the mixin is a shortcut, not a different system.

<!-- Bootstrap -->
<div class="row">
  <div class="col-md-6">Left</div>
  <div class="col-md-6">Right</div>
</div>
/* css-is-awesome */
.two-col {
  @include m.grid(2);
}

{/* or inline */}
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "1rem" }}>
  <div>Left</div>
  <div>Right</div>
</div>

Step-by-step migration

Treat this as a gradual rollout, not a rewrite. Bootstrap and cia can coexist in the same page while you convert.

  1. Install cia alongside Bootstrap. Don't rip Bootstrap out on day one. Add cia's theme + base stylesheets after Bootstrap's so cia wins specificity ties. See /docs/install.
  2. Pick a theme file. One <link> swap gives you cia's entire design language. Preview themes before committing — see /docs/tokens.
  3. Convert one component type at a time. Start with buttons — highest visibility, lowest risk, and the fastest way to sanity-check your theme. Alerts, badges, and cards are natural next stops.
  4. Replace Bootstrap utilities as you touch files. .mt-3 becomes .cia-mt-md, .d-flex becomes .cia-flex. A regex codemod handles the bulk of this — don't do it by hand.
  5. Swap Bootstrap JS for React (or nothing). Modals, tabs, dropdowns, tooltips — every Bootstrap JS plugin has a cia React equivalent. Forms and buttons often need no JS at all.
  6. Remove Bootstrap last. Delete the Bootstrap <link>, drop bootstrap from package.json, and run npm run validate-themes to confirm nothing still references Bootstrap-only variables.

Gotchas

Further reading

Theme