# GitHub switches from CSS-in-JS to CSS Modules

> GitHub switches to CSS Modules: an analysis of measured gains, the limitations of runtime CSS-in-JS, and the criteria for evaluating a React migration.

React and web performance

## GitHub switches to CSS Modules: what gains for React?

GitHub reports server-rendering and initialization gains after replacing its CSS-in-JS architecture. This experience report highlights the limitations of runtime styling without making CSS Modules a universal recommendation.

![github css modules react performance](https://sdx-development.com/media/News/github-css-modules-react-performance.webp?v=1790412081)

[Web development](https://sdx-development.com/en/news/web-development)Published on 26 September 2026 at 10:50

In its experience report published on September 25, 2026, GitHub says it completed a migration carried out over several years: since June 2026, the styling architecture concerned on github.com has relied entirely on CSS Modules, without styled-components, styled-system, or the ` sx ` prop.

 

Key takeaway 

## Real gains, but context-specific

 

GitHub reports a 55% reduction in server-rendering time in one measurement after migrating Primer, followed by gains of approximately 1% to 22% across different pages. These results describe its environment: they do not predict the benefits of a migration on another React application.

  

## Why CSS-in-JS became costly for GitHub

 

CSS-in-JS addressed concrete needs in Primer, GitHub's design system. Styles remained close to components, design tokens were integrated into the API, and TypeScript made autocompletion easier. With ` sx `, developers could customize a component from a JavaScript object.

 

According to GitHub, the difficulties became significant around 2023, as the number of components increased on some pages. In a runtime-executed CSS-in-JS solution, style processing accompanies application execution. Repeated across hundreds or thousands of components, this work can become significant.

 

01 

### Interpreting styles

 

Objects and their variations must be processed to determine the rules applicable to the component.

 

02 

### Managing classes

 

The library generates or retrieves the classes corresponding to the styles, depending on its operation and caching mechanisms.

 

03 

### Preparing server rendering

 

Collecting styles can add work to component rendering before the page is sent.

 

04 

### Initializing in the browser

 

Processing and injecting styles can contribute to the interface's initialization cost.

 

These mechanisms vary by library. Runtime-executed CSS-in-JS must therefore be distinguished from solutions that extract styles at build time: they do not necessarily have the same costs.

 

## CSS Modules: keeping components, moving the work

 

CSS Modules makes it possible to associate a stylesheet with a component while making class names local to the module by default. The component imports a class-name mapping; the tooling transforms these names to avoid collisions.

 

GitHub thus retains a component-oriented organization while producing stylesheets without relying on the same JavaScript processing of styles at render time.

 

Runtime CSS-in-JS 

### A dynamic API close to the component

 

Style logic can directly use the component's properties. This convenience must be weighed against the processing cost measured in the application.

 

CSS Modules 

### Local CSS prepared at build time

 

CSS files remain explicitly linked to components. Variants can rely on classes, attributes, and CSS variables.

 

### Dynamic styles do not disappear

 

Switching to CSS Modules does not prohibit themes or appearance changes. CSS variables can, in particular, vary colors or spacing without rebuilding all the rules in JavaScript. However, behaviors previously provided by the library must be identified and explicitly reimplemented.

 

## What gains did GitHub measure?

 

**The measurements cover several stages and several scopes.** They must neither be added together nor interpreted as an equivalent overall acceleration of github.com.

 

| Reported scope | Metric | Result |
| --- | --- | --- |
| After migrating the relevant Primer components | Server-rendering time for a page | −55% |
| After migrating Primer | Component initialization time | −25% |
| Migration extended to different github.com pages | Server-rendering time depending on the page | Approximately −1% to −22% |
| Internal Primer benchmark with 1,000 components | Runtime CSS injection compared with static CSS files | 242 ms versus 96 ms |

 

The spread of the results is instructive. The number of components, style variations, and weight of other processing differ from one page to another. A significant reduction in a heavily loaded case does not guarantee the same result on a simpler interface.

 

Point of attention 

## Faster server rendering is not an SEO promise

 

Reducing server or JavaScript work can improve the user experience. However, it does not guarantee any automatic improvement in LCP, INP, or search rankings: images, API calls, third-party scripts, caching, and business logic may remain the main bottlenecks.

 

## A gradual migration rather than a rewrite

 

GitHub started with Primer. For each component, an implementation using CSS Modules was placed behind a feature flag, compared with the old one through visual regression tests, and then deployed gradually. This first phase was completed in December 2024 for the relevant components.

 

### Maintaining compatibility with the existing code

 

github.com's code still contained approximately 7,760 ` sx ` props in April 2025. GitHub used an intermediate layer, ` @primer/styled-react `, so that these usages would continue to work during the transition. A team of eight engineers then converted 6,419 ` sx ` props in six months.

 

This temporary coexistence avoided imposing a single switch on the entire codebase. It made it possible to move forward package by package, with a more manageable validation scope.

 

### Automating known transformations

 

GitHub developed a Visual Studio Code extension and a codemod to facilitate conversions. When the final phase resumed in April 2026, 895 occurrences of ` sx ` remained. GitHub reports removing them in three weeks with two engineers and several GitHub Copilot agents.

 

This result concerns a transformation that was already defined and tooled. Automation speeds up repetitive changes; it does not eliminate the need to check dynamic styles, responsive behavior, accessibility, and regressions.

 

### Decoupling the theme system

 

The final obstacle was not limited to ` sx ` props. Part of the theming still depended on styled-components. GitHub had to decouple this logic and rely more heavily on Primer's CSS variables, particularly for its different themes and high-contrast variants.

 

This is an important point for SaaS applications: moving CSS declarations is not enough if the library also provides themes, tokens, or inherited behaviors.

 

## Should you abandon styled-components on a React application?

 

**No, not solely based on GitHub's experience report.** A productive and sufficiently performant architecture does not need to be replaced because another company faces different constraints.

 

Keep the existing solution 

### Styling is not a measured bottleneck

 

If performance meets requirements, style dynamism is useful, and the migration would deliver few benefits, keeping CSS-in-JS may be the most reasonable choice.

 

Test an alternative 

### Runtime represents a significant cost

 

Very heavily loaded pages, costly SSR, or a majority of static styles may justify a CSS Modules prototype to compare equivalent implementations.

 

### For a new project, start with the constraints

 

CSS Modules is a relevant option for using standard CSS with local scope and limiting the runtime dedicated to styles. It is not the only path: structured CSS, utility classes, or build-time generation may also meet the need. The design system, team skills, and customization requirements remain decisive.

 

## How to evaluate a migration without misjudging priorities

 

Before changing the architecture, establish a baseline on representative pages, including a particularly heavily loaded interface. The protocol must retain the same components, content, behavior, and test conditions.

 

## Six steps before a widespread migration

 
1. **Profile the existing solution.** Isolate the cost of styling from API calls, the database, and business logic.
2. **Choose a pilot.** Test a sufficiently widely used component family to produce useful measurements.
3. **Compare equivalent functionality.** Preserve variants, themes, and interactive states.
4. **Secure the rollout.** Use feature flags, visual tests, and a rollback option.
5. **Automate with review.** Entrust repetitive transformations to tools and examine complex cases.
6. **Decide based on results.** Extend the migration only if the gains justify its cost and risks.

 

### Measure the server and the browser

 

For an SSR application, track rendering time, CPU per request, and memory. Complement these with TTFB, transferred JavaScript and CSS volumes, hydration, and LCP and INP measurements from real users. These indicators describe different dimensions: an improvement in one does not guarantee an improvement in the others.

 

### Include maintenance costs

 

An architecture decision cannot be reduced to a benchmark. Migration time, design-system compatibility, test coverage, and ease of contribution must be included in the evaluation.

 

## The main lesson: keep an evolvable architecture

 

GitHub's experience report shows that a solution that is convenient at the beginning of a project can become less suitable at another scale. It also shows that a deep change can be carried out gradually, without rewriting the entire application.

 

**Measure, test on a limited scope, preserve compatibility, and validate the results**: this approach is more useful to reproduce than the choice of a library. CSS Modules can reduce an identified cost; it does not replace diagnosis.

 

Sources and documentation scope Show references

 

References indicated in the editorial brief. The figures are attributed to GitHub's experience report; the documents were not independently verified for this article.

 
- GitHub Engineering — Improving site performance by shipping more CSS, publication indicated as September 25, 2026.
- Primer React — Styling with CSS Architecture Decision Record, for architecture choices and internal benchmarks.
- Official CSS Modules documentation, for the operation of local classes.
- Primer React v37 and v38 — documentation of the transition to CSS Modules.
- styled-components — documentation on server rendering and React Server Components.

Web development

## Prepare your web application for its next update.

PHP migration, CMS updates or framework upgrades: identify compatibility issues and test essential user journeys before going live.

- Dependency compatibility checked
- Essential user journeys tested in staging
- Deployment with a rollback plan

[Plan your upgrade](https://sdx-development.com/en/contact)[Explore our expertise](https://sdx-development.com/en/services)

---

[View the HTML page](https://sdx-development.com/en/news/web-development/github-switches-from-css-in-js-to-css-modules)
