Skip to content

About

GitHub (Primer) look-and-feel theme for Gitea 1.27.x and 28.x — light, dark, auto

Topics

Resources

Stars

7 stars

Watchers

0 watching

Forks

Repository files navigation

gitea-theme-github

Build & release License: MIT

A GitHub look-and-feel theme for Gitea 1.27.x and 28.x (tested on 1.27.3, 28.0.0, 28.1.0, 28.2.0 and 28.3.0; one package for all), in light, dark and auto (follows the OS color scheme).

It is built from GitHub's own open-source design system, not by recolouring Gitea:

  • every color, size, radius, shadow, type and motion value comes from Primer Primitives (@primer/primitives 11.10.0);
  • every icon is an Octicon (19.38.0);
  • controls follow the Primer component specs.

No GitHub logos or trademarks are shipped, and the Gitea logo stays.

Theme Name in Settings → Appearance Color scheme
github-auto GitHub follows the OS (light/dark)
github-light GitHub Light light
github-dark GitHub Dark dark

Screenshots

Left: Gitea 1.27.3 default theme. Right: this theme. Same instance, same data.

Repository home Repository home: Gitea default vs GitHub theme

Issue list Issue list

Issue conversation (dark) Issue conversation, dark

Pull request diff (dark) Pull request diff, dark

Settings Settings

Install

The theme is a set of files for Gitea's custom directory (CUSTOM_PATH, $GITEA_CUSTOM). You don't change or rebuild Gitea itself.

Deployment Custom directory
Official Docker image (gitea/gitea, docker.gitea.com/gitea) /data/gitea inside the container (the /data volume)
Binary / systemd $GITEA_WORK_DIR/custom (default /var/lib/gitea/custom), or the CUSTOM_PATH shown in Site Administration → Configuration

1. Download the release package

Take gitea-theme-github-<version>-gitea1.27-28.tar.gz (or .zip) from Releases, or the gitea-theme-github artifact of the latest CI run.

It contains:

public/assets/css/theme-github-{auto,light,dark}.css   the themes (one self-contained file each)
public/assets/img/svg/*.svg                           Octicons 19.38 upgrade + Octicon replacements for non-Octicon icons
templates/**                                          GitHub-only template blocks (other themes render Gitea's upstream HTML;
                                                      repo/view_list.tmpl adds one link that stays hidden for them)
COMPATIBILITY.json                                   supported series, CI versions and build revision
INSTALL.md, LICENSE, NOTICE

2. Extract it into the custom directory

Docker (docker compose, volume ./gitea:/data):

tar -xzf gitea-theme-github-*-gitea1.27-28.tar.gz -C ./gitea/gitea

Binary / systemd:

sudo tar -xzf gitea-theme-github-*-gitea1.27-28.tar.gz -C /var/lib/gitea/custom
sudo chown -R git:git /var/lib/gitea/custom

3. Enable the themes in app.ini

[ui]
; keep the themes you already offer and add the three GitHub ones
THEMES = gitea-auto,gitea-light,gitea-dark,github-auto,github-light,github-dark
; optional: make it the default for everyone
DEFAULT_THEME = github-auto

With the Docker image, you can set the same values with environment variables instead:

services:
  server:
    image: docker.gitea.com/gitea:28.3.0   # or 1.27.3 / another supported 28.x version
    environment:
      - GITEA__ui__THEMES=gitea-auto,gitea-light,gitea-dark,github-auto,github-light,github-dark
      - GITEA__ui__DEFAULT_THEME=github-auto
    volumes:
      - ./gitea:/data

4. Restart Gitea once, then pick the theme

docker compose restart server        # or: sudo systemctl restart gitea

Choose GitHub under Settings → Appearance. Anonymous visitors get DEFAULT_THEME.

New theme files and icons are read at startup, so only this first install needs a restart. After that, updating the CSS takes effect on reload. Template changes can be hot-reloaded with gitea manager reload-templates.

Upgrading

Extract the new package over the old one (same command as step 2). It overwrites the theme files, icons and templates. Then reload the templates, no restart needed:

docker compose exec -u git server gitea manager reload-templates        # Docker
sudo -u git gitea manager reload-templates --config /etc/gitea/app.ini  # binary / systemd (your app.ini path)

Browsers pick up the new CSS on the next page load: base/head_style.tmpl carries a per-build cache key. Restart Gitea instead if the release notes list new or removed icons, or if you skip the reload.

Extracting never deletes files. If the release notes say a template was removed, delete that file from templates/ yourself.

Notes

  • Gitea version: the templates are copies of Gitea templates with added GitHub-only blocks. Where Gitea 1.27 and 28 differ, a template carries both variants and picks one from the running Gitea version (AppVer), so you can install the package before upgrading Gitea from 1.27 to 28 and keep it afterwards. Packages up to v0.1.2 only work on 1.27.x: on 28.x the repository home and file pages fail to render. Re-check the templates when a new Gitea major comes out. The CSS alone still works without the templates, but you lose the cascade layering (see ARCHITECTURE.md §3), the GitHub-style header and a few page structures.
  • Footer: shows the running Gitea version next to "Powered by Gitea" (Gitea's own [other] SHOW_FOOTER_VERSION, on by default; admins get a link to the site configuration). Set it to false to hide it.
  • If you already override templates: the package ships these templates (all under templates/): base/head_style.tmpl, base/head_navbar.tmpl, base/head_impersonate_banner.tmpl (Gitea 28.1.0's file, needed so 1.27 can load the navbar), custom/footer.tmpl, custom/gh_head_navbar.tmpl, repo/blame.tmpl, repo/commits_list.tmpl, repo/issue/list.tmpl, repo/view_file.tmpl, repo/view_list.tmpl, repo/wiki/view.tmpl, user/settings/layout_head.tmpl. If you override one of them yourself, extracting the package replaces your copy. Back it up first and merge the GitHub additions by hand: the {{if StringUtils.HasPrefix … "github-"}} blocks, and in repo/view_list.tmpl the hidden "N Commits" link (a.m-commit-count).
  • Without the templates: the repo home falls back to Gitea's Commits / Branches / Tags bar for the commit-history link. With repo/view_list.tmpl, "N Commits" sits at the right of the latest-commit row, as on github.com.
  • Icons are global: the SVG icons replace Gitea's icons for every theme. They depict the same things, drawn as Octicons.
  • Browser support: Chrome/Edge 112+, Safari 16.5+, Firefox 121+. The theme uses @layer, :has() and CSS nesting.
  • Uninstall: delete the files you extracted, remove the themes from [ui] THEMES, and restart.

Build from source

git clone https://github.com/mechiland/gitea-theme-github && cd gitea-theme-github
npm ci
npm run upstream   # cache templates + frontend sources for every version in build/gitea-versions.json
npm test           # build/packaging regression tests
npm run lint       # no literal colors outside the token layer, type/radius/shadow from tokens, selector ownership
npm run build -- --strict  # → dist/theme-github-{auto,light,dark}.css (budget: ≤ 340 KB each, minified)
npm run package    # → dist/gitea-theme-github-<version>-gitea1.27-28.{zip,tar.gz} (the drop-in package above)

Where things live:

  • src/tokens/: Primer tokens and the Gitea-variable → Primer-token map.
  • src/<folder>/: one folder per surface (foundation, controls, overlays, navigation, data-display, code, markdown, pages/*, dark). Each compiles into its own CSS @layer.
  • templates/: the GitHub-only template overrides.
  • src/icons/: the Octicon icon overrides.

Design, cascade model, ownership rules and template policy are in ARCHITECTURE.md.

Tooling used during development, against a local Gitea described in docs/CONTEXT.md:

  • tools/seed/: idempotent seed data.
  • tools/shoot/: Playwright screenshots and audits (off-palette colors, unresolved variables, non-Octicon icons, layout shift), github.com reference capture, pixel diff, CSS coverage, and a functional smoke test.
  • tools/judge/: blind A/B pairs.

Captures and reports are local artifacts: shots/, docs/reference/, docs/page-scope-report.{json,md} and dist/ are ignored by Git. The screenshot tool recreates reference captures; lint and build recreate the scope reports. docs/seed-manifest.json and docs/baseline-pre-seed.json stay tracked because the development tools use them.

Compatibility and CI / releases

One package supports both Gitea 1.27.x and 28.x. The CI matrix is defined once in build/gitea-versions.json: 1.27.3, 28.0.0, 28.1.0, 28.2.0 and 28.3.0. It is also used for upstream source checks and the package's INSTALL.md and COMPATIBILITY.json. Older 1.27 patch releases are not separate CI targets. A future Gitea release is added to this matrix after review; existing targets stay in the matrix when support is extended.

.github/workflows/release.yml runs on every push and pull request:

  1. visual regression on Gitea 1.27.3 and 28.2.0 (light/dark, desktop/mobile), with screenshot diffs and reports;
  2. run build regression tests, fetch all matrix versions' upstream sources, and check selectors against each version;
  3. build the release candidate with strict checks and the 340 KB budget, then package once for the compatibility matrix;
  4. install that unchanged archive in a fresh container for every matrix version;
  5. check native and GitHub navigation, forced password changes, repository/file/blame/wiki/issue/PR pages, theme switching, Mermaid and code copy, in light/dark at 1440/390px;
  6. retain screenshots, logs and a JSON report recording the archive SHA-256 for each version.

The visual jobs must pass before packaging the release candidate or publishing. They create their own fixed test data and compare the candidate with an explicitly approved source revision in the same CI environment. See tools/visual/README.md for local runs, reports and baseline updates.

A v* tag publishes a GitHub Release only after every matrix job succeeds, using the same archives tested above. The release job also verifies that every version's report names the same archive SHA-256. CI failure prevents publication. The .zip and .tar.gz remain named gitea-theme-github-<version>-gitea1.27-28.*.

To run the same container check locally (requires Docker and Playwright Chromium):

npx playwright install chromium
npm run package
npm run compat -- --version 28.3.0 --package dist/gitea-theme-github-<version>-gitea1.27-28.tar.gz

Use each version from the matrix to run the complete check. The tool creates disposable data and removes its container afterwards; it does not use your existing Gitea instance. Reports go to shots/compat/<Gitea version>/. See tools/compat/README.md for the checks and limitations.

Source downloads are cached in .cache/gitea-sources/<version>/; existing read-only ../gitea-src-<version> checkouts can also be used. Set GITEA_SOURCE_ROOT to a directory containing all matrix version directories to use another cache. Missing sources fail the build rather than silently reducing its compatibility checks. Page-scope reports and live caches are separated by version under .cache/page-scope/; live caches also include the instance URL and are checked against its running version:

node build/page-scope-check.mjs --version 28.3.0 --strict
GITEA_URL=http://localhost:3001 node build/page-scope-check.mjs --version 28.3.0 --live

The live command needs an authenticated shoot-tool session for that instance; after npm run upstream, normal build and source checks need no network access. Set GITEA_STORAGE_STATE to select a browser storage-state file for a live check.

Contributing

Bug reports, visual fixes and documentation improvements are welcome. Changes must remain compatible with both Gitea 1.27.x and 28.x.

  • Report a bug: open an issue with your Gitea and browser versions, steps to reproduce, and screenshots when relevant.
  • Make a change: read ARCHITECTURE.md, keep changes focused, and edit src/ or templates/ rather than generated files in dist/. Reuse the existing Primer tokens.
  • Submit a PR: run npm test, npm run lint -- --strict and npm run build -- --strict, then verify the same package across the CI matrix. For visual changes, check light and dark themes and include before/after screenshots.

Status

This is a work in progress. Pinned dependencies are in package.json; the size budget is defined in build/folders.mjs. Run npm run build for current sizes and diagnostics in dist/build-report.json.

The remaining visible differences are mostly Gitea's own features, wording and page structure, which a theme should not remove.

License

MIT.

Includes or derives from Primer Primitives, Octicons and Primer CSS (MIT, © GitHub Inc.); see NOTICE. "GitHub" in the theme name describes the visual style. This project is not affiliated with GitHub.

About

GitHub (Primer) look-and-feel theme for Gitea 1.27.x and 28.x — light, dark, auto

Topics

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages