Why Bulma Doesn't Suck (Unlike Most CSS Frameworks)

Bulma Official Banner

I've shipped Bulma in production for like 3 years now. First CSS framework that didn't make me want to throw my laptop out the window. After years of Bootstrap's bullshit, Bulma actually works like you'd expect it to.

CSS-Only Means No JavaScript Bullshit

Unlike Bootstrap's jQuery dependency hell or Foundation's JS requirements, Bulma ships as pure CSS. No version conflicts when your project already uses React, Vue, or whatever. Learned this the hard way when Bootstrap modals broke our entire checkout flow during a React upgrade. The modal backdrop started preventing form submissions, throwing null property errors in production. Spent half the night debugging this shit, missed our go-live, PM was not happy.

At least with Bulma's 191KB minified, you get everything in one file - no additional JS bundles to break your shit. Bootstrap needs separate JS files for components to even work.

Flexbox Grid That Actually Works

Bulma Logo Icon

Bulma's grid system is built on Flexbox from day one, not retrofitted like Bootstrap's mess. Want equal-height columns? Just add .column - no fighting with CSS tricks or JavaScript hacks.

Finally ditched Bootstrap after one too many Friday afternoons fighting .col-md-4 offset-md-2 math that somehow never added up to 12. Nested columns would randomly collapse on iPad Pro, breaking our mobile checkout. Spent hours in DevTools trying to figure out why 4 + 2 + 6 equaled 13 in Bootstrap's parallel universe. Bulma's auto-sizing columns saved me from ever doing that math again.

<!-- This just works, no math required -->
<div class=\"columns\">
  <div class=\"column\">Auto width</div>
  <div class=\"column\">Auto width</div>
  <div class=\"column\">Auto width</div>
</div>

Version 1.0 Finally Fixed Dark Mode

The v1.0 release added CSS Variables and native dark mode. Before this, dark mode required third-party solutions or custom Sass overrides that broke with every update.

Now you just add data-theme=\"dark\" and everything works. The CSS Variables approach means you can customize themes at runtime without recompiling Sass - something Bootstrap still can't do properly.

Class Names That Make Sense

Bulma Wordmark

Bulma uses readable modifiers like .is-primary, .is-large, .has-text-centered instead of Bootstrap's .btn-primary, .btn-lg cryptic abbreviations. When you come back to code 6 months later, you actually understand what .is-loading does without checking documentation.

The component naming is consistent across the entire framework. Every component follows the same pattern: base class + modifier. No wondering why buttons use .btn but cards use .card (looking at you, Bootstrap).

Real Performance in Production

I've deployed Bulma sites serving 100K+ users with load times under 800ms on Cloudflare. The CSS-only approach eliminates Bootstrap's JavaScript bundle that adds like 60KB and requires Popper.js. Tree-shaking gets you down to around 50KB when you only import what you actually use (buttons, navbar, grid - skip the kitchen sink).

The modular Sass structure lets you import only what you need:

// Only import what you actually use
@import \"bulma/sass/utilities/_all\";
@import \"bulma/sass/base/_all\";
@import \"bulma/sass/elements/button\";
@import \"bulma/sass/components/navbar\";

This beats including entire frameworks when you only need a grid system and buttons.

Getting Bulma Working (Without Losing Your Sanity)

Bulma Icon White

Installation: The Reality Check

npm - The Right Way (Usually)

npm install bulma

Works fine until 3am when you get this gem: Error: Expected \";\" at line 1, column 1. Turns out v1.0+ requires Dart Sass, not the old node-sass everyone still has. The error message is completely useless - just upgrade or spend your night debugging Sass parser errors:

npm uninstall node-sass
npm install sass --save-dev

Learned this the hard way migrating from v0.9.4. Two hours of build errors before I finally checked Stack Overflow. The changelog mentions it buried in bullet point #47, but who reads those anyway?

CDN - For When You Don't Give a Shit About Customization

<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css\">

Perfect for prototypes or when your PM wants "just make it look decent quickly." You get zero customization beyond CSS variable overrides, but it works in 30 seconds. The jsdelivr CDN is reliable - I've never had it go down.

Version Gotchas That Will Bite You

v0.9 to v1.0 Migration \"Nightmare\"

The HTML stays the same (thank fuck), but if you customized anything with Sass variables, prepare for pain. Some variables got renamed, and the CSS Variables system changes how theming works.

Here's what broke during my migration (took me like 8 hours instead of the "quick 30 minutes" I promised the PM):

  • Custom $primary color threw "Error: Color: undefined is not a color" with zero context about which variable broke
  • Import paths changed - @import \"~/bulma\" became @use \"bulma/sass\" but the migration docs glossed over this
  • Dark mode variables got completely renamed - spent 2 hours grep-ing the old $dark-* variables that no longer exist
  • Windows builds failed with path separator bullshit while Linux worked fine (obviously)

Budget like 4-6 hours for a complex project migration. The official migration guide helps, but doesn't cover edge cases.

Framework Integration Reality

React - Just Use the Classes

Bulma Logo Black

Forget wrapper libraries like Bloomer - half are unmaintained. Just use Bulma classes directly in JSX:

// This works fine, no wrapper needed
function MyButton({ loading, children }) {
  return (
    <button className={`button is-primary ${loading ? 'is-loading' : ''}`}>
      {children}
    </button>
  );
}

React Bulma Components is actively maintained if you want abstractions, but adds dependency weight.

Vue - Buefy is Dead, Long Live Buefy

Buefy was the go-to Vue integration, but development stalled. Check commit dates before depending on it. For new projects, use raw Bulma classes with Vue's class binding:

<template>
  <button :class=\"['button', 'is-primary', { 'is-loading': loading }]\">
    {{ text }}
  </button>
</template>

Angular - Good Luck

@angular-bulma exists but has minimal adoption. Most Angular devs just import the CSS and use classes directly. Works fine, but you lose some type safety.

Customization: CSS Variables vs Sass Drama

CSS Variables (v1.0+) - Finally Got This Right

v1.0+ finally got CSS Variables working properly:

:root {
  --bulma-primary-h: 204deg; /* HSL format is weird but works */
  --bulma-primary-s: 71%;
  --bulma-primary-l: 53%;
}

Runtime theming without Sass recompilation bullshit. Perfect for when your PM decides they want user-selectable themes at 3am. The HSL format takes getting used to, but color.adobe.com saves you from the math.

Sass Override - The Old Reliable

@use \"bulma/sass\" with (
  $primary: #3b82f6,
  $family-primary: '\"Inter\", sans-serif'
);

Still works, still powerful. Use this when you need compile-time customization or complex theme logic. Just remember - you're locked into build-time changes.

Performance: Bundle Size Reality Check

Bulma Logo White

Full Bulma CSS is 191KB minified. Sounds big until you compare:

  • Bootstrap: 163KB + like 60KB JS = 220KB+ total
  • Tailwind: 10KB-3MB depending on your cleanup game

Selective Sass importing can get you to ~50KB if you only need basics:

@import \"bulma/sass/utilities/_all\";
@import \"bulma/sass/base/_all\";
@import \"bulma/sass/elements/button\";
@import \"bulma/sass/elements/title\";
@import \"bulma/sass/components/navbar\";

PurgeCSS works well with Bulma if you're not customizing heavily. Saved me like 60% bundle size on a recent project.

Real Questions From Developers Who've Actually Used Bulma

Q

Is Bulma better than Bootstrap?

A

For modern projects? Hell yes. Bootstrap is legacy baggage with jQuery dependencies and confusing class names. Bulma's CSS-only approach means no version conflicts when you're already using React or Vue. Plus, you actually understand what .is-primary does without checking docs.Bootstrap wins when dealing with enterprise clients who insist on "industry standard" frameworks and dead browser support. But for modern browsers, Bulma will save your sanity.

Q

Can I use Bulma with React/Vue/Angular?

A

Skip the wrapper libraries - most are dead or dying. Just use Bulma classes directly in your components:

// React - works perfectly
<button className={`button is-primary ${loading ? 'is-loading' : ''}`}>
  Submit
</button>

Buefy for Vue is mostly unmaintained now. React Bulma Components is still active but adds unnecessary abstraction weight.

Q

Does Bulma support Internet Explorer?

A

Nope, and thank god. IE11 officially died June 15, 2022 - Microsoft pulled the plug. Still get this question in 2025 though. Bulma v1.0+ uses CSS Variables and modern Flexbox - IE can't even parse it.

If your client demands IE support in 2025, you're either working government contracts or dealing with someone living in 2015. Stick with Bootstrap 4 or build a separate stylesheet. Don't waste time polyfilling modern CSS for a browser that's been dead for 3 years.

Q

How do I customize Bulma without breaking everything?

A

v1.0+ uses CSS Variables for runtime theming:

:root {
  --bulma-primary-h: 204deg;
  --bulma-primary-s: 71%;
  --bulma-primary-l: 53%;
}

The HSL format is weird at first, but enables better color palette generation. Use color.adobe.com to convert your brand colors.

For complex customization, stick with Sass variable overrides - more powerful but requires build-time compilation.

Q

What's the difference between Bulma and Tailwind?

A

Tailwind is for masochists who enjoy HTML that looks like this:

<div class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">
  Button
</div>

Bulma gives you readable classes:

<div class="button is-primary">Button</div>

Choose Tailwind if you want granular control and don't mind HTML that looks like ass. Choose Bulma if you want to ship fast with maintainable code.

Q

Why is Bulma 191KB? That seems huge.

A

Compared to what? Bootstrap is 163KB + like 60KB JavaScript = 220KB+ total. Plus Bootstrap requires Popper.js for tooltips and dropdowns.

Full Bulma includes every component. In practice, selective importing gets you to ~50KB:

// Only what you need
@import "bulma/sass/utilities/_all";
@import "bulma/sass/base/_all";
@import "bulma/sass/elements/button";
@import "bulma/sass/components/navbar";

Modern bundlers + PurgeCSS eliminate unused styles automatically.

Q

Does dark mode actually work now?

A

Finally, yes. Add data-theme="dark" to your <html> tag and everything switches. Took them until v1.0 to get this right, but it's solid now.

Before v1.0, dark mode required third-party themes or custom Sass that broke with updates. The new CSS Variables approach handles theme switching at runtime.

Q

Can I just use the CDN and avoid build tools?

A

For prototypes, absolutely:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css">

You lose customization beyond CSS variable overrides, but it works instantly. The jsDelivr CDN is reliable - never seen it go down.

For production apps, you probably want build-time optimization and selective imports.

Q

Is Bulma still maintained or is it dead?

A

Very much alive. Jeremy Thomas releases regular updates. v1.0.4 dropped this past April with bug fixes and improvements. The GitHub repo shows active development.

Compare to Bootstrap's corporate bureaucracy or Tailwind's constant breaking changes - Bulma's stability is refreshing.

Q

Will migrating from v0.9 to v1.0 break everything?

A

HTML stays identical (thank god), but Sass customizations will ruin your day. Budget like 4-6 hours for a complex project (took me 8 on a Friday afternoon - Windows + deadlines = disaster):

  • $primary-color became $primary and throws "Error: Color: undefined is not a color" with no line numbers
  • node-sass throws Error: Expected ";" at line 1, column 1 with zero helpful context
  • CSS Variables break IE11 builds, triggering panic calls from QA about "the site is broken"
  • Dark mode switched from Sass mixins to data-theme attributes, breaking custom theme switching logic

The official migration guide covers the happy path, but edge cases will bite you. Test on staging first, not at 5pm Friday like I did.

Related Tools & Recommendations

tool
Similar content

Tailwind CSS Overview: Utility-First, v4.0 Features & FAQs

Explore Tailwind CSS: understand utility-first, discover new v4.0 features, and get answers to common FAQs about this popular CSS framework.

Tailwind CSS
/tool/tailwind-css/overview
100%
howto
Similar content

Angular to React Migration Guide: Convert Apps Successfully

Based on 3 failed attempts and 1 that worked

Angular
/howto/convert-angular-app-react/complete-migration-guide
76%
tool
Similar content

React Overview: What It Is, Why Use It, & Its Ecosystem

Facebook's solution to the "why did my dropdown menu break the entire page?" problem.

React
/tool/react/overview
73%
tool
Similar content

Nuxt Overview: Escaping Vue Setup Hell & Production Woes

Vue framework that does the tedious config shit for you, supposedly

Nuxt
/tool/nuxt/overview
66%
tool
Similar content

Wagmi: React Hooks for Web3 - Simplified Development Overview

Finally, Web3 development that doesn't make you want to quit programming

Wagmi
/tool/wagmi/overview
58%
tool
Similar content

Astro Overview: Static Sites, React Integration & Astro 5.0

Explore Astro, the static site generator that solves JavaScript bloat. Learn about its benefits, React integration, and the game-changing content features in As

Astro
/tool/astro/overview
55%
tool
Similar content

Next.js App Router Overview: Changes, Server Components & Actions

App Router breaks everything you know about Next.js routing

Next.js App Router
/tool/nextjs-app-router/overview
51%
tool
Similar content

HTMX - Web Apps Without the JavaScript Nightmare

Discover HTMX: build modern web applications with minimal JavaScript. Learn what HTMX is, why it's a lightweight alternative to React, how to get started, and i

HTMX
/tool/htmx/overview
49%
tool
Similar content

SvelteKit: Fast Web Apps & Why It Outperforms Alternatives

I'm tired of explaining to clients why their React checkout takes 5 seconds to load

SvelteKit
/tool/sveltekit/overview
48%
alternatives
Similar content

Redux Alternatives 2025: Modern State Management Decision Guide

Stop Fighting Actions and Reducers - Modern Alternatives That Don't Make You Want to Throw Your Laptop

Redux
/alternatives/redux/decision-guide
48%
tool
Similar content

GraphQL Overview: Why It Exists, Features & Tools Explained

Get exactly the data you need without 15 API calls and 90% useless JSON

GraphQL
/tool/graphql/overview
46%
tool
Similar content

Surviving Gatsby Plugin Hell: Maintain Abandoned Plugins in 2025

How to maintain abandoned plugins without losing your sanity (or your job)

Gatsby
/tool/gatsby/plugin-hell-survival
45%
tool
Similar content

WebAssembly: When JavaScript Isn't Enough - An Overview

Compile C/C++/Rust to run in browsers at decent speed (when you actually need the performance)

WebAssembly
/tool/webassembly/overview
43%
tool
Similar content

Fresh Framework Overview: Zero JS, Deno, Getting Started Guide

Discover Fresh, the zero JavaScript by default web framework for Deno. Get started with installation, understand its architecture, and see how it compares to Ne

Fresh
/tool/fresh/overview
41%
tool
Similar content

Framer: The Design Tool That Builds Real Websites & Beats Webflow

Started as a Mac app for prototypes, now builds production sites that don't suck

/tool/framer/overview
40%
alternatives
Similar content

Next.js Alternatives: 5 Frameworks That Actually Work

Next.js 13.4+ turned into a complexity nightmare, so I tested frameworks that don't suck

Next.js
/alternatives/nextjs/migration-ready-alternatives
37%
tool
Similar content

SvelteKit Deployment Troubleshooting: Fix Build & 500 Errors

When your perfectly working local app turns into a production disaster

SvelteKit
/tool/sveltekit/deployment-troubleshooting
35%
troubleshoot
Similar content

Fix Next.js App Router Hydration Mismatch Errors & Debug Guide

Your Components Work Fine Until You Deploy Them? Welcome to Hydration Hell

Next.js App Router
/troubleshoot/nextjs-app-router-migration-issues/hydration-mismatch-solutions
35%
tool
Similar content

Framer Performance Fixes: Speed Up Slow Sites & Boost SEO

Is your Framer site slow or failing PageSpeed? Discover common performance issues and immediate fixes to speed up your Framer website, improve SEO, and prevent

/tool/framer/performance-issues-fixes
35%
integration
Similar content

SvelteKit, TypeScript & Tailwind CSS: Full-Stack Architecture Guide

The stack that actually doesn't make you want to throw your laptop out the window

Svelte
/integration/svelte-sveltekit-tailwind-typescript/full-stack-architecture-guide
34%

Recommendations combine user behavior, content similarity, research intelligence, and SEO optimization