Skip to content

Unlocking inclusive design: how Primer’s color system is making more inclusive

How Primer’s updated light and dark theme color contrast strategy resolved hundreds of color-contrast-related accessibility issues over one thousand use cases.

An example of new colors on GitHub with Primer. There are demonstrations of color contrast improvements in a few sections: default text with accessible hyperlinks, secondary text with additional content and an underline hyperlink, and a hyperlink with icon. There is also a subtle green change in the “comment” button with the text that says “solving hundreds of accessibility issues.”

Over 100 million developers around the world come to GitHub to build software. Primer, GitHub’s open source design system, is responsible for creating inclusive, responsive and efficient experiences for a diverse range of users. The Primer team aims to enable all user interface (UI) components to be built leveraging Primer. At Primer’s foundation is our color system, a way of defining and applying consistent colors across the Primer UI components and themes. As part of GitHub’s larger accessibility strategy, the Primer Design team committed to improving color contrast in both default light and dark mode. This task is more complex than shifting some hex values in a few components.

The Primer color system has two modes: light and dark. Each mode has several themes, including a default theme, dimmed theme, high contrast theme, and themes for users with color vision deficiencies. Our design systems works with all themes and modes without requiring any extra adjustments.

In order to meet our goal and truly be a home for all developers, we created a color contrast strategy that addresses the hundreds of color contrast issues that were present in Primer. By strategically focusing on our foundations, we were able to make a big impact on improving the accessibility of This resulted in passing color contrast requirements and resolving hundreds of accessibility issues across more than one thousand use cases. This improvement to the color infrastructure is at the foundation of more exciting and accessible updates coming to GitHub UI. Read on to learn more about how we did it.

Accessibility at the foundation

Our goal was to improve the color contrast of Primer components in both light and dark color modes. We worked efficiently to achieve this by improving accessibility at our foundations through changes to Primer Primitives. Color tokens from Primer Primitives are based on a functional color system that supports multiple color modes and are used to style various elements (text, backgrounds, borders, icons, and more). By focusing on Primer Primitives, we could make color contrast changes in one place and see the updates across all Primer patterns, scaling accessibility improvements to all UI leveraging Primer.

Primer Primitive Layers: Higher level tokens reference lower level tokens. Base tokens include our color scales. There are three transparent layer squares floating on top of each other. The bottom layer is “base tokens,” middle layer, “Functional tokens,” and top layer, “component tokens.”

We partnered with the brand team to ensure that the changes we were making were true to GitHub’s brand. At the beginning of this project, we experimented with major adjustments to different parts of the UI in both brightness and hue. However, we chose to scope our changes to accessibility improvements, intentionally leaving larger brand-impacting changes as a separate issue. The plan was to make the smallest possible change to the overall user experience and focus on achieving contrast goals.

Shaping the strategy


With such a large task ahead, we needed to define a clear strategy. First, we needed to identify both the contrast violations as well as the appropriate levels of Primer’s foundations that we would need to edit. To do this, we performed a comprehensive audit of our Primer primitives. This was a large task in itself, because we had to audit different use cases across all color themes, amounting to hundreds of variations.

Next, we looked at Primer components and how they were using colors. In a system at scale, things can get complicated quickly because the requirements depend on the context and combinations in which colors are used. We immediately identified over 100 color pairs—for example, a text color paired with a background color in use across Primer components. To achieve contrast goals, we needed to ensure these color combinations fulfilled contrast requirements.

Deeply understand the color relationships and WCAG Guidelines

After the audit was completed we had a long list of color pairs with specific contrast requirements. Some colors had more complex relationships as they had to meet a contrast requirement with multiple colors. Our default text is one such example: it not only has to meet the 4.5:1 contrast with the default and muted background, but also a 3:1 contrast with the link color and secondary color. Additionally, colors are often part of multiple color pairs, which means that improving one pair may break the contrast for another.

Manually testing the contrasts began to significantly slow us down. We needed to solve this and we did it the GitHub way: using code and automation.

Solutions and relationships: In a complex system changes to one part have cascading effects. There is a diagram that shows the 4.5:1 contrast requirement between Default text and canvas, canvas and Secondary text, and canvas and link. There is another diagram with 3:1 requirements between Default text and link, and Default text and secondary text.

Codify our learnings to automate for scale

To make our color contrast checks more efficient, we automated the process using a script. Instead of manually testing individual color pairs in Figma, we changed the tokens in the code and created a script that could automatically perform contrast checks for all tokens across all themes.

Once we defined the required contrast ratios for all color pairs, the script generated a table in the command line interface (CLI), which allowed the team to keep track of changes and quickly identify which pairs had passed and failed.

Automating the work: Programmatically checking 100+ color contrast combinations. A visual of a command line interface shows a long list running the full width of the screen with a contrast ratio calculation in one column, and to the column next shows the minimum required (4.5:1 or 3:1), with green checks and a couple of red “x” to indicate errors.”

One of the more challenging issues we faced was checking colors with opacity, as the result could vary depending on the background color used. To solve this problem, we created a two-step approach:

First, for every color pair, we checked if the background color was semi-transparent. If it was, we used a blend algorithm to create a solid color with the page background, resulting in generating new color pairs.

Second, for each of those pairs, we checked if the text color was semi-transparent. If it was, we used the same blend algorithm with the now solid background color to create a solid text color.

Leveraging both approaches allowed us to calculate the contrast between the two solid colors

The script significantly improved the team’s work speed, taking only a few seconds to run compared to the time-consuming task of creating and testing each pair individually. We ran the script after making changes, assuring that changing one color contrast did not break another pair. This alleviated our concerns with updates across all color themes.

In fact, this workflow worked so well that we integrated the script as a GitHub action that now runs on every pull request to Primer. If a change is introduced that breaks color contrast, we can catch it before it makes it into production.

Rollout and results

After making contrast changes, the team needed to check if they were working well. We used a tool called a “feature flag” to gradually introduce the changes to some users, testing them before making them available to everyone and ensuring everything was functioning as intended before going live.

We gathered feedback on ‌contrast changes by conducting qualitative user interviews with colleagues from various teams, and observing their reactions with the feature flag enabled. After completing this phase, they enabled the feature flag for all staff and carefully monitored it for a few weeks while collecting feedback.

With a strong focus on our foundations, we were able to make significant strides towards improving the accessibility of, resolving hundreds of accessibility issues across over a thousand use cases. And, of course, to help our designers and developers, we documented everything to ensure that our guidelines, recommendations, and best practices continue to help designers and developers create cohesive, inclusive, responsive, and efficient experiences using our libraries.

Our path ahead

We believe that accessibility should be at the heart of design, and we’re proud to have made such a significant impact on Primer’s accessibility through our work on the color system. We look forward to continuing to make Primer more inclusive for all, so stay tuned for more updates from us!

Explore more from GitHub



The latest on GitHub, from GitHub.
The ReadME Project

The ReadME Project

Stories and voices from the developer community.
GitHub Actions

GitHub Actions

Native CI/CD alongside code hosted in GitHub.
Work at GitHub!

Work at GitHub!

Check out our current job openings.