GitAlike

Browser extension · GitHub ⇄ GitLab · any forge · any skin

Use any forge, keep your muscle memory.

GitAlike makes every major forge speak one UI. Point it at GitHub, GitLab, Codeberg/Gitea, Bitbucket, Gerrit or any instance you add, and it re-skins the page as the product you know best — colour, words, navigation, reference markers and keyboard shortcuts included. Nothing else makes GitHub read like GitLab — and back. It changes nothing about what the site does, and every change is reverted the moment you switch it off.

No account No network requests No data collected GPL-3.0 Chromium, Firefox & their forks

GitHub project page, default GitHub default GitLab skin ↔

How it works

Three steps, no account, and it is invisible the moment you turn it off.

Pick a skin

Open the popup and choose GitHub UI, GitLab UI or Bitbucket UI — for the whole web, or for the one host you are on.

The site repaints

GitAlike re-points the site's own design tokens and matches the other product's words, navigation and shortcuts — with no reload.

Switch it off

Every change is recorded and undone exactly. With the skin off, the extension is completely inert — nothing to clean up.

See it

Live captures of the real sites at 1280×900. Pick a source forge and a page kind, and the capture shows that page wearing every skin it can — drag a divider to reveal one, or focus it and use the arrow keys. All five sources are here: GitHub, GitLab and Codeberg in full, and Bitbucket and Gerrit from their app shells (their pages render client-side).

GitHub project page

A horizontal tab bar, shown as GitLab — a vertical sidebar-style column — and as Bitbucket — a Source / Pull requests / Pipelines sidebar in Atlassian blue.

GitHub project page, default Default · GitHub GitLab UI Bitbucket UI
Default · GitHub GitLab UI Bitbucket UI Open full size

Not just a theme

A theme changes the colours and stops there. GitAlike also matches the other product's words, navigation, reference markers and shortcuts — then undoes every change when you switch it off.

Colour

Each site's own design tokens (GitHub's Primer, GitLab's Pajamas) are re-pointed at the other product's palette — light and dark.

Words

"Pull request" ⇄ "Merge request", "Insights" ⇄ "Analytics", "Actions" ⇄ "CI/CD". Ordinary page copy only — never inside code, inputs or editable regions.

Navigation

Repo tabs are relabelled, reordered and re-oriented — GitHub's bar becomes GitLab's grouped sidebar, and GitLab's sidebar becomes GitHub's flat tab row.

References

A pull/merge-request link shows the other product's marker: #42 ⇄ !42.

Shortcuts

The other product's g-combos work, so the muscle memory you built on one forge carries over to the other.

Reversible

Every change is recorded and reverted exactly when the skin is switched off. With it off, the extension is completely inert.

The same page, in each product's words

Same repository, same commits, same history. Only the words on the screen change.

GitAlike does not gloss the page with a dictionary. It swaps the navigation for the applied product's own menu — that product's vocabulary, that product's order, that product's words for the things the two forges name differently. What you are reading is that product's UI, not a translation of yours, and the page keeps every commit, branch, file and review it always had.

So one open code review is a merge request under the GitLab UI, a pull request under the GitHub UI, and a pull request under Bitbucket's — and its reference marker changes with it, !42 ⇄ #42. A feature the applied product simply has no page for is never renamed into nothing: it stays where it is, marked ≠ GitLab, so the page says so instead of pretending.

The mapping lives in each skin's own plugin file under src/plugins/skins/, so a label cannot drift from the skin it belongs to — and adding a skin is adding one folder.

Concept GitHub GitLab Bitbucket Gitea / Forgejo Gerrit
Source tabCodeRepositorySourceCodeBrowse
Issue trackingIssuesWork itemsJira issuesIssues—
Code reviewPull requestsMerge requestsPull requestsPull requestsChanges
Continuous integrationActionsCI/CDPipelinesActions—
InsightsInsightsAnalytics—Insights—
File finderGo to fileFind file———
SnippetsGistsSnippetsSnippetsSnippets—
Project boardsProjectsIssue boards—Projects—
Reference marker#42!42#42#42change no.

A dash is one of two very different things, and the table does not pretend otherwise. Bitbucket has no insights page at all — issues live in Jira, and it keeps no snippets on a repository. Bitbucket, Gitea and Gerrit have no modelled file-finder label: the extension only translates a word it has an entry for, so a blank there means "not mapped", not "does not exist". Every cell above is read from a plugin's own nav / phrases table, so the page cannot claim a word the extension does not actually swap.

The design systems behind the UIs

Layout, palette, type and interaction are what make a forge feel like itself — and what your hands learn. These are the pieces a skin has to reproduce.

The words table above shows what each product calls a thing. This one shows how each product builds it: the shape its navigation takes, the colour it owns, the type it sets and the muscle memory it teaches. A skin that only recolours gets one row of this table and drops the rest — which is why GitAlike re-points the palette, re-orients the navigation and re-labels the controls, then reverts all of it.

Factor GitHub GitLab Bitbucket Gitea / Forgejo Gerrit
Layout & structure
Design system Primer Pajamas Atlassian Design System (ADS) Gitea's own, Bootstrap-derived PolyGerrit, Material Design
Navigation shape Horizontal repo tab row Vertical, grouped super-sidebar Vertical, flat sidebar Horizontal tab row (overflow-menu) Header views and query tabs; no repo tabs
Page frame Dark app bar → tab row → content beside an About rail Light super-topbar → left rail → one wide content column Dark blue app bar → left sidebar → card content Top bar → tab row → bordered cards Header → change list → info panel per change
Landing page File table, README, About rail README-first, then Project information Card overview with its own navigation File table, then README Change list / query results
Metadata lives In a right-hand About rail Full-width Project information block Sidebar and header badges Repo header, then sidebar Change info panel
Colour
Accent Blue #0969da Blue #1f75cb, purple #7759c2 Atlassian blue #0052cc Green #609926 Material blue links on grey; no brand hue at rest
Header surface Near-black #000000 app bar Light grey #ececef — the rail's own grey Dark blue #0049b0 bar Its own bar (--color-nav-bg) Header drawn from the applied skin
Primary action Green Code / Merge Blue Code / Merge Blue Clone / Merge Green primary button Material blue button
Dark theme Canvas #0d1117 Canvas #1f1e24 Canvas #1d2125 Its own [data-theme] dark mode PolyGerrit's root properties, dark
Typography
Sans stack System UI — -apple-system, Segoe UI, Noto Sans GitLab Sans (Inter-based) Atlassian Sans (Inter-derived); Charlie for brand System UI stack Roboto
Mono stack ui-monospace — SF Mono, Menlo, Consolas GitLab Mono (JetBrains Mono-based) Atlassian Mono System mono stack Roboto Mono
Type character Dense and tabular, ~14px base Airier and documentation-like, ~14px base Medium density, ~14px base Compact and utilitarian, ~14px base Material, dense list, ~14px base
Interaction & muscle memory
Corner radius 4 / 6 / 8px, three steps 4 / 8px, two steps 3 / 8px, two steps 3–4px controls Small, Material radius
Elevation Hairline borders, faint shadow Flat, hairline borders Flat with borders, occasional shadow Bordered cards, minimal shadow Material elevation — shadowed cards
Icons Octicons Pajamas / GitLab SVGs Atlassian icons Gitea's own SVGs Material icons
Keyboard g p pull requests, g b projects, g n notifications; t file finder, / search g m merge requests, g p projects, g t todos; / search No g-combos; its own shortcut set is small Ships no g-combos of its own No g-combos; a change view is navigated with single keys

Every cell is the product's own choice, not GitAlike's: the palette values are the ones the colour gate scores in tests/fixtures/target-chrome.json, the radius and type stacks are the skins' --gs-* declarations, and the layout, landing page and navigation rows are the anatomy in FORGE-UX.md. The keyboard row is the muscle memory itself — and the one a skin can hand across forges: GitAlike replays the applied product's g-combos on a site that honours synthetic keys and delivers them as trusted clicks where it does not, so the combos you know keep working after the UI changes. Bitbucket reuses GitLab's layout pass, so a Bitbucket skin is GitHub's or GitLab's shape in Atlassian's palette. Gitea ships none of these combos of its own, so the applied product's are delivered as clicks on its own navigation links, and the Bitbucket skin maps none at all.

How it compares

Most tools here answer make this site nicer or make this site work better. Only one answers make one forge read like another.

Most browser tools for GitHub and GitLab answer one question: make this site look nicer. A smaller set answers a second: make this site work better. Neither is what GitAlike does. GitAlike answers a third — make one forge read like another, and back — which is the one no other tool is built for.

Two axes separate them: how deep a tool reaches (colour → words and navigation → behaviour), and which way it points (one product, or two of them reciprocally).

One-way one product, on its own terms Reciprocal two products read as each other
Colour the palette GitSkin · userstyles GitAlike
Words & navigation labels, menu order, markers, keys — GitAlike
Behaviour workflow, API Refined GitHub · Octotree —

Every other tool here lives in the left-hand column. GitAlike is the only one of them that works reciprocally — it is the only one that can show a GitHub page as GitLab and a GitLab page as GitHub, from the same install. That is the cell it occupies, and it is not the same cell as any of the others.

Shaded rows are ones GitAlike does not win. It is a skin: it changes how a page reads, not what the site does, and it ships three built-in skins rather than a marketplace.

Capability GitAlike GitSkin Userstyles Refined GitHub
Repaints the palette●●●◐
Renames the product's words●○○○
Rebuilds navigation●○○◐
Swaps reference markers (#42 ⇄ !42)●○○○
Delivers the other product's g-shortcuts●○○◐
Works in both directions●○○○
Covers GitLab as well as GitHub●○◐○
Community themes / a marketplace○●●○
Improves a forge's own UX rather than translating it○○○●
Unifies the API or CLI across forges○○○○
Survives upstream DOM churn◐ pinned selectors + daily canary◐ network adapters○ often breaks◐ active team
No network requests, no remote code●○ CDN adapters●●
Works on self-hosted / enterprise instances●○ GitHub-only●●

● does it · ◐ partial or adjacent · ○ does not. "Survives upstream DOM churn" is partial for everybody that touches the DOM: no skin is immune to a site rebuilding its markup, and each tool answers it differently — GitAlike pins every selector and runs a daily canary against the live sites, which catches a change instead of silently shipping a broken page. It does not prevent the change. Where no tool does something, the row says so rather than being left out.

GitSkin

The closest neighbour — one-way

The most sophisticated approach to the same hard problem: themes target abstract components, resolved to GitHub's DOM by adapters, with a marketplace and a five-level scale from Primer tokens up to global CSS. It is GitHub-only, and its adapters are delivered from a CDN, so a theme needs network requests. It answers make GitHub look like anything.

Userstyles (Stylus, GitHub-Dark, …)

The DIY substitute — one-way

A large free ecosystem that recolours a site and stops. CSS cannot rename what a button says, reorder a menu, or swap a reference marker, and a style that reaches into a page's structure tends to break when the site changes. That is not a knock — for a dark theme it is the better tool, and the community that moved off Stylish onto Stylus for its privacy is exactly this audience.

Refined GitHub

The benchmark — one-way

The strongest answer to make GitHub itself better: a large, org-backed, MIT extension that has shipped so many good ideas GitHub absorbed dozens of them. It is not a reskin and it does not translate GitHub into anything — it improves GitHub on GitHub's own terms, which is a different job from the one here.

GitAlike

The other cell — reciprocal

Not a theme and not an enhancer: a translation between two products. Same repository, same commits, same history — read in the UI you already know, in either direction, and reverted the moment you switch it off. If the question is make GitHub nicer, use Refined GitHub. If it is a dark theme, use Stylus. If it is I work on both and keep hitting the wrong muscle memory, that is the one here.

Works with your forges

Three skins over five source products, and no rebuild to add your own. GitHub, GitLab, Codeberg/Gitea, Bitbucket and Gerrit all work — out of the box, or after one prompt — and any site you set up can wear any skin.

github.com gitlab.com GitHub Enterprise Server self-hosted GitLab Codeberg (Forgejo) gitea.com (Gitea) bitbucket.org Bitbucket Data Center Gerrit + GitHub skin + GitLab skin + Bitbucket skin + any instance you add

Add any instance by visiting it or typing its address — no rebuild. Paste a link and GitAlike highlights the product it looks like (/-/merge_requests is GitLab, /pull/ GitHub, /pulls/ Gitea/Forgejo, /pull-requests/ Bitbucket, /c/…/+/… Gerrit), so you usually only confirm it. Bitbucket is both a skin and a source; Gerrit is a source with no bundled host, so you add your instance. Adding a self-hosted host asks the browser to grant that one origin. Sourcehut is the next candidate.

Plugins

GitAlike is assembled from two kinds of plugin, and the registry is open — anyone can add one. A skin is a target UI a page is made to look like; a source is a forge's markup. They are independent — any source can wear any skin — so one new forge or one new UI extends every page the extension already touches. Each is a self-contained folder under src/plugins/: its definition, its tests, and a stylesheet for a skin.

Skins

One folder in src/plugins/skins/: the product's vocabulary, navigation order, profile menu and shortcuts — not just its palette, which lives beside it. Its own tests run with npm test.

Bitbucket UI GitHub UI GitLab UI

Add a skin →

Sources

One folder in src/plugins/sources/: the DOM hooks a skin reads, the live page the daily canary watches, and its own tests, so a rename upstream fails a check instead of a user.

Bitbucket Gerrit Gitea / Forgejo GitHub — Primer GitLab — Pajamas

Bitbucket Cloud and Gerrit are client-rendered sources: their app shells are canaried, and their palettes are re-pointed through the design tokens each reads (Atlassian --ds-* on Bitbucket, PolyGerrit's root properties on Gerrit), so they recolour without reaching into the app. Gerrit's chrome lives in open shadow roots, so its copy, navigation and query pages are reached from the content scripts too.

Add a source →

The registry is open — contributions are welcome. Adding one is meant to be small: a plugin is one folder — its definition and its tests, plus a stylesheet for a skin and, for a forge people host, a host entry. node tools/new-plugin.mjs skin <name> (or source <name>) writes that skeleton for you, and this list is generated from the plugins — so it cannot drift from the code. A new source brings another forge (Sourcehut is the next candidate); a new skin brings another target UI. The rules are the same for everyone — GPL-3.0-or-later, no monetisation, and your own original mark rather than a vendor's. Propose a plugin → Contributing guide →

Nothing leaves your browser

GitAlike collects no data and makes no network requests. Both stylesheets are bundled and the mark is an inline data URI.

It stores only your on/off choices and the instances you add, in the browser's own synced extension storage. Nothing read from a page is stored or sent anywhere.

Read the full privacy policy →

Which sites it can reach

Only five hosts are granted at install — github.com, gitlab.com, codeberg.org, gitea.com and bitbucket.org. A self-hosted instance is granted when you add it: the popup asks for that one origin, a prompt you only see if you asked for that host. There is no all-sites grant, and its scripts load only on hosts you have set up and granted.

Questions

Does it send my data anywhere?

No. GitAlike makes no network requests at all — no CDN, no remote configuration, no telemetry. The stylesheets ship in the bundle and the mark is an inline data URI. It stores only your on/off choices and the instances you add, in the browser's own synced storage.

Which sites can it access?

The five bundled hosts — github.com, gitlab.com, codeberg.org, gitea.com and bitbucket.org — are granted at install. Everything else is asked for one origin at a time, when you add it, so a self-hosted GitHub Enterprise, GitLab, Bitbucket Data Center or Gerrit instance triggers a single prompt for its host, and nothing is granted before that.

Does it work on my self-hosted instance?

Yes. Add the host by visiting it or typing its address — no rebuild. Adding it asks the browser to grant that one origin. GitHub Enterprise Server, self-hosted GitLab, Bitbucket Data Center and Gerrit all work, and Codeberg (Forgejo) and gitea.com are already covered.

How does it know which forge a link is?

When a host is not set up yet, the popup reads the address and highlights the product it looks like, so a pasted deep link needs only a confirmation: /-/merge_requests/42 is GitLab, /pull/42 GitHub, /pulls/42 Gitea/Forgejo, /pull-requests/42 Bitbucket and /c/project/+/42 Gerrit — even on a host it has never seen. It reads the URL only, never the page, and makes no network request; a bare host it cannot place is left for you to choose.

Does it change what the site does?

No. It changes how the page looks and reads, not what it does: no requests are intercepted and no data is touched. It never rewrites text inside code, inputs or editable regions, and every change is reverted when you switch the skin off.

Which browsers does it run in?

The two extension platforms, so it covers their forks too. The Chromium build runs in Chrome, Edge, Brave, Opera, Vivaldi and the rest; the Firefox build needs Firefox 142 or newer and runs in the forks that track it, such as LibreWolf, Floorp and Zen.

Is it free?

Yes — GPL-3.0-or-later, no account and no paid tier. The source is on GitHub, and you can build it yourself with npm run build.

Install

Two clicks, or build it yourself.

Chromium

Chrome, Edge, Brave, Opera, Vivaldi and the other Chromium-based browsers share the API — one build.

  1. Download the ZIP and unzip it.
  2. Go to chrome://extensions and turn on Developer mode.
  3. Load unpacked → choose the unzipped folder.

Load unpacked takes the folder, not the ZIP. Most Chromium browsers install from the Chrome Web Store, where GitAlike is live.

Firefox

Needs Firefox 142 or newer, and works in the forks that track it (LibreWolf, Floorp, Zen, …). The ZIP is unsigned, so Firefox loads it temporarily — it is gone when the browser restarts. A permanent install comes from addons.mozilla.org.

  1. Download the ZIP.
  2. Go to about:debugging#/runtime/this-firefox.
  3. Load Temporary Add-on… → choose the ZIP itself; it does not need unzipping.

Every major store

GitAlike targets the two extension platforms, so it runs in the Chromium browsers (Chrome, Edge, Brave, Opera, Vivaldi, …) and in Firefox and the forks that track it (LibreWolf, Floorp, Zen, …). It is live on the Chrome Web Store and on addons.mozilla.org, with Microsoft Edge Add-ons and Opera to follow. Until those are listed, the ZIPs above install it today.

  • Chromium
  • Chrome
  • Edge
  • Brave
  • Opera
  • Vivaldi
  • Firefox
  • LibreWolf
  • Floorp
  • Zen

From source

No runtime or build dependencies — the build only generates the two per-browser manifests.

npm run build            # -> dist/chromium and dist/firefox
npm test                 # unit tests, no browser needed
node tools/compare/e2e.mjs       # Playwright end-to-end test against the live sites