The most complete and thorough guide to migrating our Carbon Tutorial: v10 to v11

Josefina Mancilla
Oct 5 · 7 min read

Last month we released our beta version for Carbon v11. As part of that, we did extensive research to learn how our users migrated in the past — their pain points, their desired experience, and more — in hope of creating a better migration experience. During the course of that research, one of you lovely people in the Carbon community suggested, “Hey, why don’t you document how you migrate the Carbon tutorial so we can see what it’s like?” So we did just that. 😜

Let me preface this by saying that the tutorial migration was a unique experience since each branch progressively develops the application. Things might feel a bit repetitive, but we want to share our unfiltered experience for the sake of transparency. Additionally, this tutorial migration was part of our first beta release and subsequent testing. Issues and implementations are bound to change.

Step 1

The very first step starts with installing our new package . We then removed our old packages: , , and . Things did break, but that was expected.

Easy stuff first

After installing the new package, we went for the lowest hanging fruit first: updating all our component and icon imports in and to point to that package instead of .

Getting sassy

Our next move was to update our styles to use sass modules. We didn’t have to update any packages for this since the tutorial was already on .

We updated the import for Carbon styles in to utilize the method for including styles, as well, as point to our new package since the styles are now included in it.

We then did the same thing for

At this point, we tried to start the server and see if things were working. They were not. Ha! Of course not. The migration gods would never.

The issues we ran into:

  • was including some component exports that weren't being exported in . This was fixed and released in a patch version: #9476.
  • After we thought everything was fixed and the server should be able to start, it was still throwing an error saying it couldn’t find our stylesheet for some reason. We did all the usual debugging, including nuking our , to no avail. Everything seemed right, so it didn't make sense. Eventually, we realized we just had to update our package to the latest version. We also updated our other dependencies to be safe.
  • After we thought everything was for real fixed, we ran into some more errors. We realized that the new package was depending on our old packages, but wasn’t including them as peer dependencies. As a workaround, we re-installed our old packages that we had previously removed. This issue has been fixed since then in this PR: #9533.

All in a grey’s work

Finally, we were able to start our server. It was thrilling to see the landing page with our UI Shell, but because we themed our shell in v11, it was now white (our default theme). Our design specs called for a g100 shell, so we had to fix this. Thankfully, we made inline theming easy-peasy in v11, so we were able to utilize some of our new features.

We imported our new component into , and wrapped our header and content with it. Then we added the styles for theming into .

Our header was now g100! But we noticed the landing page text disappeared, and after further inspection, we realized there were some styles that weren’t being applied anymore. This was because the content was now wrapped around a div but the styles were using the selector . If you're unfamiliar with CSS, is the adjacent selector. Our styles were saying, "look for which should be a direct sibling of ," when in actuality our DOM looked like . So we added the following style overrides to :

.bx--content {
margin-top: 3rem;
background: var(--bx-background);

Step 2

The biggest migration for this step was moving to our new CSS Grid. Prior to this update, our tutorial wasn’t even using our React grid components, so it was a huge jump.

A sass half full

We started out by updating to use sass modules, since we already knew what that process looked like. Unlike before, however, we had to include any sass we were using — theme tokens, spacing tokens, mixins, etc. — at the top of each file where we were writing our styles. In addition to those imports, some token and mixin names were updated in v11, so we also had to update those. Most notably, color tokens were completely renamed, and some mixins and tokens no longer include the prefix.

The final changes looked like this:

Note: the selectors that were completely deleted or completely new were updated at the very end of migrating this step, after migrating the grid.

Finding the correct path for the sass imports required a little digging. We knew that the root would be , so then we looked at the repo to find where each thing lived. We updated and in this same way.

Oops, I grid it again

After updating all the sass, we moved on to . We started with changing the components import to point to . We also added and to the list of imports. Since the way CSS grid works means we no longer need a row component, we didn't import .

The obvious, easy part was to replace all the grid and column divs with their respective component. We were undecided about what to do with the row divs. “Do we delete them? But they’re using custom classNames for styles. Will the grid styles still work if we leave the divs in? Who knows.” So we decided to start our server and just see where the chips were falling. Of course, everything was broken.

After learning that leaving the row divs was breaking the grid styles, we decided we had to utilize sub-grids to create faux rows (we finally support nested grids in v11). We did this by using a that spanned the full 16 columns. We assigned the custom className for the row to this column. Then, we nested a within it, which ten contained smaller columns. Ultimately, here's what the changes looked like:

Note: we did have to update some of the custom styles for this page, mostly to fix some spacing issues for the banner appearances (mentioned in the code snippet).

Our page was finally looking like our design specs. However, we ran into an issue where the primary button in the first tab appeared to be missing. After we inspected the DOM, we realized it was still there, but it was invisible because it wasn’t recognizing the component-specific tokens.

The button component token is grayed out but the text color token is not.

This issue is being tracked and worked on here: #9358. We added the following code to our as a temporary workaround (copied from our storybook):

The sass never ends

After finally finishing the landing page, we moved on to the repo page. To keep it short and sweet, we essentially did the same thing:

  1. Migrate to use sass modules
  2. Migrate imports to point to
  3. Migrate the grid just like we did for the landing page

This page was a lot easier to migrate since we really only had one row and way fewer custom styles.

Step 3

If you’ve done our tutorial, you know that this step wasn’t specifically about using Carbon. In this step, we add GraphQL so we can get actual GitHub data for our table. We did do some migration around this, but nothing related to Carbon. We simply updated the GraphQL dependencies and imports we were using since they had been deprecated in favor of a new package. Sound familiar? 😉

Step 4

In this branch of the tutorial, all we really do is add content to the bottom row of the landing page. Migrating this content was pretty simple since we already knew how to migrate the grid.

We started out by updating which contains the code for our and components:

  1. Import and from .
  2. Since is the nested section that contains our columns, we replaced the outermost wrapper with , passing along all necessary classNames.
  3. Then we replaced all the column divs with , also passing along classNames
  4. Finally, we just had to make sure that was being wrapped by a (spanning full width) where it was being used in so that the nested grid would work correctly.

The last step was to update to use sass modules like we did with previous steps, which was pretty easy to do at this point.

Helpful resources

If you’ve stuck around, thanks for coming to my TED talk. We hope that this was as much a learning experience for you as it was for us. To learn more about v11, check out our migration docs, example template, and GitHub Discussions.

Josefina Mancilla is a Front End Developer based out of Austin, TX working on the Carbon Design System. The above article is personal and does not necessarily represent IBM’s positions, strategies, or opinions.

Questions or comments about Carbon? Reach out at or tweet us @_carbondesign.


Carbon is the design system for IBM software products.


Carbon is the design system for IBM software products. It is a series of individual styles, components, and guidelines used for creating unified UI.

Josefina Mancilla

Written by

Developer on Carbon Design System by day 💻, gym rat/ triathlete/climber by night 🚲, dog mom always. 🐶


Carbon is the design system for IBM software products. It is a series of individual styles, components, and guidelines used for creating unified UI.