COMMAND REFERENCE

fxcss install

bash
fxcss install owner/theme                      # into your default profile
fxcss install owner/theme --with compact-tabs  # optional sheets, permanently
fxcss install ~/src/my-theme                   # a local checkout works too
fxcss install --list-profiles                  # see what it found first

Put a theme into the Firefox profile you actually use — the cross-platform replacement for each theme's own install.sh (and the answer for themes whose install script never covered Windows). Resolution is the same as try: a GitHub owner/name or URL with --ref/--commit, or a local directory. As with try, the theme's own install script is never executed.

It finds your real profiles by parsing profiles.ini in the platform's Firefox directory (macOS ~/Library/Application Support/Firefox, Windows %APPDATA%\Mozilla\Firefox, Linux ~/.mozilla/firefox plus the snap and flatpak locations) and installs into the profile Firefox itself would open. --profile <name-or-path> overrides; with several profiles and no clear default, interactive runs get a picker and scripts get an error — CI is never prompted. Profiles kept somewhere unusual can be added to the search with FXCSS_PROFILE_ROOTS=/path/to/dir, mirroring FXCSS_FIREFOX_ROOTS.

Firefox's default profile decides only for install, which is choosing where to put a theme. Every command that acts on one already installed — uninstall, upgrade, rollback — looks for the profile that has it, so a theme installed deliberately into your Developer Edition profile is still found by a bare fxcss uninstall. adopt looks for the opposite: a chrome/ folder fxcss did not install. Firefox's default breaks the tie only when more than one profile qualifies, and --profile always wins.

The picker and --list-profiles say which Firefox each profile belongs to, because default-release and dev-edition-default are one word apart in a list of hashed directory names — and installing into the wrong one looks exactly like the theme not working:

example
Several Firefox profiles exist:
  1. default-release        [Release]              …/Profiles/8f2b1a.default-release  (Enter)
  2. dev-edition-default    [Developer Edition]    …/Profiles/c41d9e.dev-edition-default
  3. work                   [unrecognised]         …/Profiles/7ab3.work

The label comes from the directory suffix Firefox itself assigns, so a profile you named yourself reads [unrecognised] rather than being guessed at.

Run it without --with and it offers the theme's optional stylesheets rather than leaving you to find them in the repository:

example
  This theme ships optional stylesheets:
    1. compact-tabs
    2. theme-dracula
    …
    Numbers separated by commas, `all`, or Enter for none.
  Include:

Options that cancel each other out

Some of a theme's optional sheets are alternatives rather than additions. Installing two colour themes is two @imports, and nothing about that warns you — the later one silently wins outright, leaving a browser that looks like neither the one you picked nor the one before it. install measures for this and stops:

console
$ fxcss install AdamXweb/WhiteSurFirefoxThemeMacOS --with theme-nord,theme-dracula

  theme-dracula and theme-nord are alternatives, not additions: both set the
  same 122 declaration(s), so whichever loads last replaces the other entirely
    :root { --gnome-browser-before-load-background: #282a36 }  vs  { …: #2e3440 }

  Refusing to install stylesheets that cancel each other out — only one
  of them would have any effect, and which one is decided by import
  order rather than by you. Pick one, or pass --force.

It is a measurement, not a guess about names. Two sheets are alternatives when they set the same properties on the same selectors — provable from their text, and true whatever they are called. Matching on a theme- prefix would be a convention rather than a fact: it would tell a theme shipping theme-blue and theme-compact that those clash when they compose perfectly well, and miss a pair named dark.css and nord.css. Sheets that agree exactly are not in conflict, because two options setting the same border radius the same way compete for nothing.

try reports the same thing and continues — a throwaway profile is a fine place to watch two colour themes cancel out — and tweaks says so before screenshotting a --combo that cannot take effect.

What this does not see. It compares declarations, so it catches sheets fighting over the same property. Two sheets that rearrange the same area through different selectors — WhiteSur's tabs-swapclose and windows-swapclose both move a close button and share no declarations at all — are invisible to it. fxcss tweaks --combo a+b proves those from the rendered pixels — and says so itself: a combo that renders identically to one of its parts alone is called out in TWEAKS.md as not a real combination on that Firefox. Silence from the static check is "nothing measurable", never "verified compatible"; the pixels are the judge.

When the theme's default branch has moved on since its newest release, that choice is put to you as well — a tag can be a year behind a fix you are looking for, and equally the branch can be mid-rewrite, so neither is right to assume:

example
  The default branch has moved on since the latest release:
    1. release v2.0                 2025-01-03  what the author last published  (Enter)
    2. latest commit on master      2026-08-14  newer than the release — fix tab colours
  Install [1-2]:

Scripts and CI never see any of these prompts: without a terminal the release wins, as before, with a one-line note that --commit exists.

The install is what a theme's install script does, done carefully:

  • the complete replacement is prepared before your existing chrome/ moves to a timestamped chrome.backup-* sibling; a failed swap restores it;
  • any --with optional sheets go where the theme's own @imports expect them, or load after the base theme through an import-only wrapper;
  • toolkit.legacyUserProfileCustomizations.stylesheets is enabled in user.js — inside a clearly marked block, so it can be removed cleanly — together with any configuration/user.js the theme ships;
  • a manifest (chrome/fxcss-install.json) records every file written, its sha256, and where the theme came from — which repo, which ref, and whether that ref was a release or a branch.

Restart Firefox after installation; it reads userChrome.css at startup. See uninstall to remove a theme later.