Skip to content
JazzmedoPublic

Latest commit

 

History

18 Commits

Folders and files

Repository files navigation

ShellTint: your desktop shell's colours on Firefox and 130+ websites

MIT license Firefox 140 or newer Chromium 120 or newer Linux: DankMaterialShell, Caelestia, Noctalia, end-4 and matugen

ShellTint

ShellTint colours Firefox from your desktop shell. It reads the Material You palette that DankMaterialShell, Caelestia, Noctalia, end-4's illogical-impulse or matugen generated, themes the browser toolbar with it, and restyles more than 130 websites (YouTube, GitHub, X, Reddit, Wikipedia and others) using Catppuccin's userstyles recoloured with your palette. When the shell changes theme, the browser and open tabs follow within seconds, without a reload.

It also runs in Chromium-based browsers (Chromium, Chrome, Brave, Vivaldi, Edge, Helium) for everything except the toolbar colours, which need Firefox's theme API.

ShellTint has two parts: the browser extension, and a small local helper (a native messaging host) that reads your shell's colour files and builds the website styles.

Features

  • Toolbar, tabs, address bar and menus take the shell's colours (tonal or vivid style).
  • Catppuccin userstyles for 130+ sites, recompiled with your palette on every theme change — only the ones you actually visit, so a theme change costs about a second.
  • Light and dark follow the shell, or can be forced.
  • Pause styling per site from the toolbar popup, or turn it off everywhere; the button counts the styles in use.
  • Style your own self-hosted SearXNG, Homepage, boringproxy and OpenMediaVault.
  • Your own CSS per site, with syntax highlighting and suggestions; settings and styles back up to a zip.
  • Detects the shell automatically; any matugen output works as a fallback.
  • Collects no data.

How it works

 shell colour file                     ShellTint helper (native host, Python)
 (DMS, Caelestia, Noctalia, ──watch──▶  normalises roles, light/dark
  end-4, matugen file)                        │
                                              ▼
                                ~/.cache/shelltint/palette.json
                                              │
                                              ▼
                              builder (Node): Catppuccin userstyles
                              recompiled with the palette
                                              │
                                              ▼
                              ~/.cache/shelltint/userstyles/current/
                                              │
        browser extension  ◀──native messaging──┘
          ├─ browser.theme      → toolbar colours
          └─ scripting.insertCSS → per-site CSS in matching tabs

Prerequisites

  • Firefox 140 or newer, or a browser on a 140+ base: Zen, LibreWolf, Floorp, Waterfox.
  • Linux.
  • Python 3.8+.
  • Node.js 18+ with npm (a system package or nvm both work).
  • curl.
  • flock, from util-linux.
  • One supported shell (see Supported colour sources) or a matugen output file.
  • The extension's "Access your data for all websites" permission. Firefox may ask for it after install; ShellTint's Overview page shows a button if it is missing. Without it no website can be styled.

Fedora:

sudo dnf install python3 nodejs npm curl util-linux

Debian/Ubuntu:

sudo apt install python3 nodejs npm curl util-linux

Arch:

sudo pacman -S python nodejs npm curl util-linux

Install

  1. Install the extension from addons.mozilla.org: https://addons.mozilla.org/firefox/addon/shelltint/

  2. Install the helper:

    git clone https://github.com/Jazzmedo/ShellTint
    cd ShellTint
    ./scripts/install.sh

    It copies the helper to ~/.local/share/shelltint, installs the builder's npm dependencies, registers the native messaging manifest, detects your shell and builds the website styles once.

  3. Restart the browser, then open ShellTint (toolbar button → settings) and check the Overview page.

Chromium-based browsers

  1. Download shelltint-<version>-chromium.zip from the latest release and unzip it to a folder you'll keep.
  2. Open chrome://extensions (Brave: brave://extensions), turn on Developer mode, choose Load unpacked and pick that folder. Its ID should be paiglabcdaphmocanlbnikkipilidmfk.
  3. Install the helper as in step 2 above, then restart the browser.

Website styles, My styles and backup work as in Firefox. Toolbar colours are Firefox-only: Chromium has no API for an extension to recolour the browser. For a similar result, choose Settings → Appearance → GTK in Chromium, which follows your GTK theme, so a matugen-coloured GTK theme matches your shell.

Flag Effect
--prefix DIR Install the helper to DIR instead of ~/.local/share/shelltint.
--no-build Skip the first style build; it runs when the browser connects.
--dry-run Print what would be done and change nothing.
--with-matugen-hook Print a matugen config snippet that rebuilds styles while the browser is closed. Your matugen config is not edited.

The native messaging manifest goes to ~/.mozilla/native-messaging-hosts/shelltint.json, which Firefox, Zen and Floorp read. LibreWolf, Waterfox and Flatpak browser folders get a copy only if they already exist. Chromium-based browsers get theirs in NativeMessagingHosts inside their config folder (~/.config/chromium, ~/.config/google-chrome, ~/.config/BraveSoftware/Brave-Browser, ~/.config/vivaldi, ~/.config/microsoft-edge, ~/.config/net.imput.helium), again only when that folder exists; the list is in scripts/chromium-browsers.sh.

Supported colour sources

Source File Light / dark
DankMaterialShell ~/.cache/DankMaterialShell/dms-colors.json isLightMode in ~/.local/state/DankMaterialShell/session.json
Caelestia ${XDG_STATE_HOME:-~/.local/state}/caelestia/scheme.json the file's mode field
Noctalia v4 ${NOCTALIA_CONFIG_DIR:-~/.config/noctalia/}colors.json colorSchemes.darkMode in settings.json
Noctalia v5 ~/.cache/shelltint/sources/noctalia.json, written by a user template (below) the template's mode
end-4 illogical-impulse ${XDG_STATE_HOME:-~/.local/state}/quickshell/user/generated/colors.json inferred: dark when the background is dark
Matugen file any JSON or CSS-variables file you choose the file's mode / is_dark, else inferred

Notes:

  • Noctalia v4 only exports 16 roles. ShellTint derives the missing container and surface levels from them, and lists that as a warning on the Overview page.
  • The matugen file source accepts flat JSON ({"primary": "#..."}), {"mode": ..., "colors": {...}}, matugen's nested {"colors": {"primary": {"dark": ..., "light": ..., "default": ...}}}, or CSS variables. Accepted names include --primary, --mg-primary, --md-sys-color-primary, primary and camelCase such as surfaceContainerHigh.

Auto-detection

With the source set to Auto, ShellTint uses the first one whose file exists and parses, in this order:

dms → caelestia → noctalia → end4 → matugen

To use a different one, open ShellTint → Colours and pick the source. For a matugen file, choose "Matugen file", enter the path and press Check.

Matugen template

This template writes every colour plus the mode, in a format the matugen file source reads. It was rendered with matugen 4.2.0 in both modes: the output is valid JSON, {{ mode }} renders as lowercase dark / light, and the loop emits all 50 roles.

Save as ~/.config/matugen/templates/shelltint.json:

{
  "mode": "{{ mode }}",
  "is_dark": <* if {{ is_dark_mode }} *>true<* else *>false<* endif *>,
  "colors": {<* for name, value in colors *>
    "{{ name }}": "{{ value.default.hex }}"<* if not {{ loop.last }} *>,<* endif *><* endfor *>
  }
}

Add to ~/.config/matugen/config.toml:

[templates.shelltint]
input_path = '~/.config/matugen/templates/shelltint.json'
output_path = '~/.cache/shelltint/sources/matugen.json'

Then in ShellTint → Colours choose "Matugen file" with the path ~/.cache/shelltint/sources/matugen.json.

Noctalia v5 template

Noctalia v5 no longer writes a palette file. Add a user template that writes one. Not tested on this machine; Noctalia's template syntax is matugen-style, so the template above should work unchanged.

[theme.templates.user.shelltint]
input_path = "~/.config/noctalia/templates/shelltint.json"
output_path = "~/.cache/shelltint/sources/noctalia.json"

Copy the matugen template above to ~/.config/noctalia/templates/shelltint.json. The Noctalia source picks the file up automatically.

Settings

Setting Values Default Where
paletteSource auto, dms, caelestia, noctalia, end4, matugen auto Colours
customPalettePath path to a JSON or CSS file empty Colours (Matugen file)
mode follow, dark, light follow Colours
toolbarTheming on / off on Overview, popup
toolbarStyle tonal, vivid tonal Colours
websiteStyling on / off on Overview, Websites, popup
disabledSites site list empty popup; managed under Websites → Paused sites
siteInstances site id → one hostname or URL per line empty Websites → Self-hosted sites
autoCheckUpdates on / off on Maintenance

A paused site covers its subdomains: pausing youtube.com also pauses m.youtube.com.

Self-hosted sites

Four Catppuccin styles are written for software you host yourself, so upstream can only name a placeholder address (homepage.example.com). Put your own address under Websites → Self-hosted sites and that style starts applying:

Style Notes
SearXNG
Homepage Already matches any host starting homepage., e.g. homepage.home.local.
boringproxy
OpenMediaVault

A line is a hostname (subdomains included) or a full URL to style only that path. To change how one of them looks, write your own CSS for it under My styles.

Homepage needs one extra piece. It paints the page with html { background-color: rgb(var(--bg-color)) }, an r g b triplet, and the Catppuccin style puts a hex colour there — an invalid rgb(), which the browser drops, leaving Homepage's stock slate behind the themed cards. Paste docs/styles/homepage.css into a new style under My styles to set the colour directly and match the rest of the desktop.

My styles

Write your own CSS for any site, like Stylus. Open ShellTint → My styles → New style, or click the toolbar button on a site and choose "New style for this site".

  • Sites: one per line. A hostname such as example.com covers its subdomains, a URL such as https://example.com/forum/ covers only pages under it, and * means every site. Lines starting with # are comments.

  • CSS: plain CSS, applied after the Catppuccin style so your rules win ties. Use !important where a site's own CSS is more specific.

  • Replace the Catppuccin style: turn on "Turn off the Catppuccin style on these sites" to use only your CSS there.

  • Shell colours: every style can use the palette as variables, and pages update when the shell changes theme:

    body {
      background: var(--shelltint-surface) !important;
      color: var(--shelltint-on-surface) !important;
    }
    a { color: var(--shelltint-primary) !important; }

    Material roles are --shelltint-<role> (primary, on-primary, primary-container, secondary, tertiary, error, surface, on-surface, surface-container, surface-container-high, outline and more). Once website styles are built, Catppuccin's recoloured slots are available too, as --shelltint-ctp-<slot> (base, mantle, crust, text, mauve, blue and so on). The editor lists them all with swatches.

  • Editor: CSS is syntax-highlighted, and suggestions for properties, common values and the --shelltint-* variables pop up as you type (Ctrl+Space opens them anywhere). ↑/↓ pick, Enter or Tab accepts, Esc closes.

  • Backup: Maintenance → Back up to zip saves your settings and every style, each as its own .css file. Restore from zip adds the styles in the backup, replaces those you still have with the backed-up version, keeps the rest, and applies the backed-up settings.

  • Styles are stored in the extension and work even when the helper isn't running. Pausing a site or turning off website styling also turns off your styles there.

Rebuilds

  • While the browser runs, the helper watches the active source's files. When they change and settle, it writes a new palette, recolours the toolbar and rebuilds the website styles in the background. Open tabs switch to the new styles without a reload.

  • When the browser connects, the helper checks Catppuccin for new userstyles, at most once every 10 minutes (turn off with autoCheckUpdates).

  • To rebuild while the browser is closed, add ShellTint's hook to matugen (print the snippet with ./scripts/install.sh --with-matugen-hook):

    post_hook = '~/.local/share/shelltint/builder/scripts/matugen-hook.sh'
  • Manual: ShellTint → Maintenance → Rebuild styles now, or Check Catppuccin for updates.

Troubleshooting

Helper not connected

  • Check that ~/.mozilla/native-messaging-hosts/shelltint.json exists and its path points at an existing, executable shelltint_host.py.
  • Check that python3 is on your PATH.
  • Restart the browser after installing the helper.
  • Flatpak and Snap browsers run sandboxed. They need the manifest inside their sandbox and may not be able to start the helper at all; a native package is recommended.

Zen: never create ~/.zen. Zen treats that folder as its profile folder and opens an empty profile. Zen reads native messaging manifests from ~/.mozilla/native-messaging-hosts, which the installer already covers.

No source detected

  • Open ShellTint → Colours; the detected-sources list shows each file ShellTint looked for and why it was rejected.
  • Make sure the shell has generated a palette at least once (change the wallpaper or theme).
  • Otherwise use the Matugen file source.

Some styles failed or a site looks wrong

  • Build output is in ~/.cache/shelltint/build.log. Failed styles are also listed under Websites.
  • Pause the site from the popup.

Reset the website styles

rm -rf ~/.cache/shelltint/userstyles

Then use Maintenance → Rebuild styles now.

Uninstall

./scripts/uninstall.sh          # helper and native messaging manifests
./scripts/uninstall.sh --purge  # also ~/.cache/shelltint and ~/.config/shelltint

Then remove the extension from about:addons.

Privacy and permissions

ShellTint collects no data and sends nothing anywhere. The extension talks only to the local helper. The helper's only network access is downloading Catppuccin's public userstyles:

Permission Why
nativeMessaging Talk to the local helper that reads the shell's colour files and serves the compiled CSS.
theme Colour the toolbar, tabs and menus.
scripting + access to all websites Insert the site CSS into pages that a style matches.
webNavigation Notice navigations and frames, so styles apply early and follow in-page navigation.
storage Keep your settings.

Development

node --test "builder/test/*.test.mjs"
python3 -m unittest discover -s host/tests
./scripts/package.sh    # web-ext lint + Firefox zip, Chromium build (dist/chromium) and zip
./release.sh --dry-run  # tests and package only; ./release.sh tags, pushes and publishes a GitHub release

To add a colour source, see docs/adapters.md. The helper protocol is in docs/protocol.md.

Credits

License

MIT. See LICENSE.

Releases

Packages

Contributors

Languages