Using IBM's Carbon Design System with NextJS

For a NextJS project I'm working on at the moment the decision was made to get up and running quickly using IBM's pretty excellent Carbon design system[1]. On the face of it, this should have been a pretty simple process. After all, I've configured Next to use much more "complex" and twisty tools like Tailwind before without a second thought, so how hard could Carbon be?

Turns out, it was a bit of a headache. To be clear, this wasn't any fault of the Carbon installation process or the team behind it. Nor was it an issue with Next. If anything, both groups have tried to make things as easy as possible. It's just that, in doing so, they have inadvertently made it harder to get the various parts to talk to one another, whilst actual issues became obfuscated by slightly roundabout documentation (in places) and no real community guidance – hence this article.

That said, I'm definitely no expert in any of the tools or technologies covered here, so consider everything served with a handy pinch of salt. All I can say is that after about five hours of debugging, I now have a NextJS repository that can import, display, and extend Carbon components. Hopefully these steps can help others achieve the same outcome 😉

The Prerequisites

I'm not aiming to write a full-fat guide or tutorial here, so I'm going to assume that you already have a NextJS project set up (I'm specifically using Next v10), hooked up to whatever CI pipeline you want, and version controlled using Git. Similarly, you'll need to have npm installed and preferably some kind of IDE. Oh, and I personally use Windows 10, though I don't think anything I'm doing will be any different on Mac or Linux.

Basically, as long as you can run some kind of local command (e.g. npm run dev) and see a default Next site spin up on localhost, you're ready for the next steps 🎉 If not, check out some of the further reading below first.

Installing Carbon

Carbon is split across a few different packages, so depending on exactly what you need there is some flexibility. For most scenarios though, you'll want to run the following to install the core components, React-specific stuff, and the UI icons that the design system uses:

npm install carbon-components carbon-components-react carbon-icons

If you're using TypeScript (like we were) you can then grab the Directly Typed packages with:

npm install @types/carbon-components
npm install @types/carbon-components-react

Great, that covers all the main design system files and functionality, but there is one more third-party dependency that Next will need to make sense of things: Sass. Let's grab that as well:

npm install sass

Luckily, Next comes preinstalled with a lot of the additional dependency needs that Carbon normally asks for, so you won't need to worry about other tools mentioned in their docs (i.e. webpack). It also magically sorts out the Sass integration, all you need to do is point it in the right direction.

To do that, create a new file in the root directory of your project and name it styles.scss. Open it up and paste in the following, save it, and forget it about forever:

@import './node_modules/carbon-components/scss/globals/scss/styles.scss';

The last step is to import those global styles into your app itself, so open up the _app.tsx (or _app.jsx if not using TypeScript) in your pages folder and import it at the top of the file:

import '../styles.scss'

And that's it. Seriously, Carbon should just work at this point 🎉

Using Carbon Components

Right, but let's just make sure of that first by actually using a Carbon component. Because it's an incredibly simple one (and only a single line of code), let's start with a loading spinner. Open up any page template (e.g. index.tsx or index.jsx) and import the Loading component at the top:

import { Loading } from 'carbon-components-react'

Then, within your returned JSX for the existing page template, add the following anywhere:

<Loading description="Loading indicator" withOverlay={false} />

Now (if you haven't already) open up the site on localhost and you should hopefully see one of these:

An animated loading icon of a line rotating in a circle.
Round and round and round and round and...

With the site open, we can also just check that attributes are being passed correctly by amending the Loading component like so:

<Loading description="Loading indicator" withOverlay={false} small />

Go back to your browser and you should see the spinner is now only about one character tall 👍

Explore Other Articles


Animated Content Placeholders

What do you do when a website has loaded but the content is still being fetched from an API? One answer is to fill the page with animated placeholders, creating a skeleton of what the user can expect, with a dash of CSS animation to let them know that something's still going on behind the scenes.

Further Reading & Sources


Want to take part?

Comments are powered by Webmentions; if you know what that means, do your thing 👍


  • <p>The combination of the Carbon design system and NextJS should make for rapid website development, but I ran into a few small hurdles getting them to play nicely with one another using existing documentation and community guidelines.</p>
  • Murray Adcock.
Article permalink

Made By Me, But Made Possible By:


Build: Gatsby

Deployment: GitHub

Hosting: Netlify

Connect With Me:

Twitter Twitter

Instagram Instragram

500px 500px

GitHub GitHub

Keep Up To Date:

All Posts RSS feed.

Articles RSS feed.

Journal RSS feed.

Notes RSS feed.