Browser support at GitHub: data over guesswork
GitHub’s engineering philosophy holds that software isn’t fully shipped until it’s fast, and JavaScript is a major factor in page performance. One lever the company pulls is the syntax and polyfills it ships. In January 2022, GitHub updated its compiler to output native ES2019 code, which enabled shipping native syntax for optional catch binding. The next step is moving to ECMAScript 2020 syntax, including optional chaining and nullish coalescing operators, which will cut JavaScript payloads by about 10kb across the site.
Because GitHub is built on progressive enhancement, users on older browsers still get core functionality through plain HTML and CSS, while those on modern browsers receive the enhanced, faster experience. The approach to browser support isn’t based on hunches, but on usage data collected from User-Agent headers, plus tooling for linting, polyfills, and compatibility validation.
What the usage data says
Roughly 95% of requests to GitHub’s web services come from browsers with identifiable user-agent strings. Another 1% omit the header entirely, and the remaining 4% are scripts or programs like Python (2%) and cURL (0.5%). GitHub encourages users to run the latest versions of Chrome, Edge, Firefox, or Safari, and the traffic data from May 9–13, 2022 shows that most visitors do.
- Chrome dominates with more than 70% of requests.
- Firefox accounts for roughly 12%.
- Edge brings about 7%.
- Safari sits at 4.2%.
- Opera trails at 1.4%.
- All other vendors combined account for well under 1%.
Version distribution falls off sharply: more than 70% of traffic comes from the latest release of each browser, 18% from the previous release, and less than 1% from three versions back. This pattern indicates that focusing engineering effort on Chrome, Firefox, Edge, and Safari, in that order, delivers the most impact.
Release cadence varies. Safari ships one major version per year alongside macOS and iOS, and GitHub sees a steady upgrade rhythm among Safari users—especially in the 15.x line, with usage peaks roughly every eight weeks between January and April. Chrome, Edge, and Firefox all follow four-week release cycles. Chrome traffic peaks every four weeks, and for about two weeks a single version typically represents over 80% of that browser’s traffic.
These patterns confirm that evergreen browsers are the norm; targeting single versions is no longer viable. GitHub’s Web Systems Team removed the last user-agent-based conditionals in January 2020 and recorded an internal architecture decision record explicitly forbidding that pattern due to maintenance costs.
The long tail of older browsers
Still, universal access matters. One percent of 73 million users is still 730,000 people. The remaining browser traffic includes older versions of mainstream browsers alongside a vast array of niche clients: Chromium forks like QQ Browser (0.085%), Naver Whale (0.065%), and Amazon Silk (0.003%); Firefox forks like IceWeasel (0.0002%) and SeaMonkey (0.0004%); and more exotic agents from TVs, e-readers, and even refrigerators. GitHub has seen close to 20 million unique user-agent strings in 2022 alone.
Logged-in versus logged-out usage is another useful lens. About 20% of visits come from logged-out sessions, but that share rises sharply among older browsers. For example, 80% of Amazon Silk traffic is logged-out, dropping logged-in Silk usage to roughly 0.0006% of all visits. Users on forked browsers often also use evergreen ones: SeaMonkey users spend only 37% of their time on that browser, with the rest coming from Chrome or Firefox.
This distinction matters because logged-out and logged-in activities demand different things from the page. Reading issues, cloning repositories, and browsing files are largely read-only and rarely require JavaScript. Replying to issues, reviewing pull requests, starring repositories, and editing files all depend on richer interactions. Without JavaScript, users can still log in, comment (minus the rich markdown toolbar), browse syntax-highlighted code, search repositories, and star, watch, or fork projects—popover menus even work via the native HTML <details> element.
Engineering for a fragmented browser landscape
No engineering team can test against hundreds of browsers across thousands of OS and version combinations. GitHub instead leans on industry-standard practices: static analysis and polyfills to deliver a solid baseline experience.
Linting catches what transpilers miss
ESLint is a core part of the workflow, configured not just for style but for cross-browser bugs. The amilajack/eslint-plugin-compat plugin guards against unsupported features that GitHub isn’t prepared to polyfill—ResizeObserver, for one. The keithamus/eslint-plugin-escompat plugin flags syntax that browsers don’t support and that isn’t transpiled or polyfilled. These plugins also catch subtle quirks: older versions of Edge supported destructuring, but in certain cases threw a SyntaxError. Linting for that corner case let GitHub ship native destructuring syntax everywhere while preventing regressions, removing kilobytes of transpiled code and helper functions in the process.
Polyfills: fewer, but better
Earlier versions of the codebase relied heavily on packages like mdn-polyfills, es6-promise, template-polyfill, and custom-event-polyfill. Managing that sprawl was burdensome and sometimes hurt performance—ShadowDOM adoption was postponed for years because available polyfills were too slow.
The current strategy is a minimal, curated list of polyfills for features that are easy and low-impact to patch. These live in GitHub’s open-source browser-support repository, which also exposes a public compatibility table. That repository includes a function that checks whether a browser has the base functionality needed to run GitHub’s JavaScript—requiring that globals like Blob, globalThis, and MutationObserver exist. Browsers that fail the check still execute JavaScript, but uncaught exceptions won’t be sent to failbot, the error-reporting service. Filtering out noise from unsupported browsers keeps error reporting actionable. Relevant code from failbot.ts:
import {isSupported} from '@github/browser-support'
const extensions = /(chrome|moz|safari)-extension:\/\//
// Does this stack trace contain frames from browser extensions?
function isExtensionError(stack: PlatformStackframe[]): boolean {
return stack.some(frame => extensions.test(frame.filename) || extensions.test(frame.function))
}
let errorsReported = 0
function reportable() {
return errorsReported < 10 && isSupported()
}
export async function report(context: PlatformReportBrowserErrorInput) {
if (!reportable()) return
if (isExtensionError()) return
errorsReported++
// ...
}

Validating changes with real data
When introducing something like native optional chaining syntax, GitHub engineers use an internal CLI that merges mdn/browser-compat-data with internal usage analytics. The tool outputs a Can I Use–style feature table tailored to GitHub’s actual traffic for the requested feature—handy for pasting directly into pull request descriptions, putting the data in front of reviewers to keep decisions aligned with usage reality.
browser-support-cli $ ./browsers.js optional chaining #### [javascript operators optional_chaining](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Optional_chaining) | Browser | Supported Since | Latest Version | % Supported | % Unsupported | | :---------------------- | --------------: | -------------: | ----------: | ------------: | | chrome | 80 | 101 | 73.482 | 0.090 | | edge | 80 | 100 | 6.691 | 0.001 | | firefox | 74 | 100 | 12.655 | 0.014 | | firefox_android | 79 | 100 | 0.127 | 0.001 | | ie | Not Supported | 11 | 0.000 | 0.078 | | opera | 67 | 86 | 1.267 | 0.000 | | safari | 13.1 | 15.4 | 4.630 | 0.013 | | safari_ios | 13.4 | 15.4 | 0.505 | 0.006 | | samsunginternet_android | 13.0 | 16.0 | 0.020 | 0.000 | | webview_android | 80 | 101 | 0.001 | 0.008 | | **Total:** | | | **99.378** | **0.211** |
The same CLI generated all the tables in this post and can export compatibility data as JSON that can be imported into Can I Use. It can produce similar tables for quick reference during feature review.
Making the call: progressive enhancement in practice
Concepts like progressive enhancement are what turn our browser principles into a working product. The goal is straightforward: deliver a complete, high-quality experience to the majority of users, while still providing a functional and useful experience for those on older or less capable browsers. We don't treat browser support as a binary "yes or no" decision. Instead, we layer features and capabilities so that the core functionality of GitHub remains accessible, with enhancements added for those who can take advantage of them.
This approach keeps us honest about where we invest engineering effort. We're not chasing support for every obscure rendering quirk; we're prioritizing the features and performance that matter to the largest segment of our user base. For everyone else, we ensure the essential tasks can still be completed, even if the interface is not as rich.
Grounding decisions in data
Our stance on browsers is not based on guesswork or personal preference. We constantly monitor the real-world usage patterns of our visitors—the browsers they load, the devices they use, and the capabilities those environments support. This telemetry and tracking inform everything from which CSS features we can safely rely on to which JavaScript APIs we should polyfill.
This data-driven approach prevents us from making changes that would inadvertently harm a significant portion of our audience. It also gives us the confidence to remove legacy workarounds when the data shows that the browsers requiring them have dipped below a meaningful threshold. The tooling we have in place ensures that our stated principles are consistently applied, not just in new code, but across the entire platform as it evolves.
Balancing experience and reach
The constant interplay between data and principles is what allows us to balance a fast, modern experience with broad compatibility. By leaning on progressive enhancement and rich user data, GitHub makes deliberate choices about what to build and for whom. The result is a platform that remains quick and feature-packed for the many, without locking out the long tail of users on older systems. For that final group, we make sure the basics are never out of reach, even as we push forward with the latest web technologies for everyone else.



