Menu
GitHub Engineering·September 25, 2026

Migrating GitHub's Frontend Styling from CSS-in-JS to CSS Modules for Performance and Scalability

This article details GitHub's extensive multi-year migration from a CSS-in-JS solution (styled-components with `sx` prop) to CSS Modules for their Primer Design System and broader codebase. The primary motivation was to address performance challenges related to client-side style initialization, server-side rendering overhead, and scalability issues as their component count grew. The migration involved a phased approach utilizing feature flags, wrapper components, automated tooling, and a significant engineering effort to achieve substantial performance gains and simplify their frontend architecture.

Read original on GitHub Engineering

The Challenge: Performance Bottlenecks with CSS-in-JS

GitHub's Primer Design System, powering many of its UI experiences, faced significant performance challenges with its existing CSS-in-JS solution. As the number of components on pages increased, the overhead of client-side style initialization and server-side rendering (SSR) became substantial. This architectural decision, while offering benefits like TypeScript support and co-location, introduced runtime costs due to the dynamic nature of inline objects used for styling, impacting initial page load times and overall scalability.

The Solution: Embracing CSS Modules for Static Styling

The Primer team identified CSS Modules as a suitable alternative. This approach allows for native CSS features with built-in encapsulation (local class names by default), significantly reducing the risk of global selector collisions. Crucially, CSS Modules eliminate client and server runtime behavior; styles are compiled into static CSS stylesheets and sent as part of the HTML, directly addressing the performance bottlenecks of CSS-in-JS.

Incremental Migration Strategy and Architectural Safeguards

  1. Primer Component Migration (2023-2024): Components were individually updated to CSS Modules. To ensure stability, a "wrapper" component approach (`@primer/styled-react`) was used, allowing existing `sx` prop usage to continue while new consumers could use the performant `@primer/react`.
  • Feature Flags: A critical tool for safe rollouts. Each component's styles were toggled between old (CSS-in-JS) and new (CSS Modules) via feature flags, allowing for gradual exposure from internal teams to all GitHub users. This provided early feedback and allowed for stress testing in production.
  • Visual Regression Tests: Used to verify that the visual output remained identical across styling solutions, minimizing regressions.
  • Automated Tooling: Custom VS Code plugins and codemods were developed to automate the translation of `sx` props to CSS Modules, significantly accelerating the migration of thousands of instances across the codebase.
  • Theming Decoupling: The final stage involved migrating GitHub's multi-theme support away from `styled-components`-enabled JavaScript utilities to pure CSS variables, another phased rollout using feature flags.
ℹ️

Performance Wins Achieved

The migration yielded significant performance improvements: a 55% reduction in server-side rendering time for Primer components and a 25% decrease in component initialization time. This demonstrates the impact of moving dynamic, runtime-heavy styling to a static, compile-time approach in large-scale applications.

This case study highlights the importance of incremental re-platforming for large-scale systems, where significant architectural shifts are introduced gradually with robust safety nets like feature flags, comprehensive testing, and automated migration tooling. It underscores how even frontend styling choices can have profound impacts on server-side performance, deployment complexity, and overall developer experience.

CSS-in-JSCSS ModulesFrontend ArchitecturePerformance OptimizationGradual MigrationFeature FlagsDesign SystemGitHub Engineering

Comments

Loading comments...