firefox-theming
Firefox Theming
Source of truth
Firefox ships CSS inside omni.ja (a zip file). Always extract and read source files before writing or auditing userChrome rules.
Extract source
OMNI=$(ls /nix/store/*firefox-unwrapped*/lib/firefox/browser/omni.ja 2>/dev/null | head -1)
OMNI_TK=$(ls /nix/store/*firefox-unwrapped*/lib/firefox/omni.ja 2>/dev/null | head -1)
DEST=/tmp/ff-omni
mkdir -p "$DEST" && cd "$DEST"
# CSS
unzip -o "$OMNI" "chrome/browser/skin/classic/browser/*.css" "chrome/browser/skin/classic/browser/**/*.css" 2>/dev/null
unzip -o "$OMNI_TK" "chrome/toolkit/skin/classic/global/*.css" "chrome/toolkit/skin/classic/global/**/*.css" 2>/dev/null
# DevTools
unzip -o "$OMNI" "chrome/devtools/skin/*.css" 2>/dev/null
# XUL/HTML
unzip -o "$OMNI" "chrome/browser/content/browser/browser.xhtml" 2>/dev/null
Verify element existence: grep 'id="element-id"' $DEST/chrome/browser/content/browser/browser.xhtml.
Reference
references/source-map.md — complete variable/element/class reference for:
- Browser CSS (
chrome/browser/skin/classic/browser/): browser-colors, browser-shared, toolbarbuttons, urlbar-searchbar, urlbarView, tabs, sidebar, contextmenu, identity-block, panelUI-shared, unified-extensions, downloads, findbar, and more - Toolkit CSS (
chrome/toolkit/skin/classic/global/): global-shared, popup, menu, findbar, in-content/common-shared, design-system/tokens-shared - DevTools CSS (
chrome/devtools/skin/): variables.css theme variables - browser.xhtml: structural IDs, urlbar IDs, sidebar IDs, toolbar button IDs, key classes, non-existent IDs
Consult the source-map first. Extract and read the actual source file when the map lacks detail.
Workflow
- Consult source-map.md for the section being edited
- Extract source CSS from omni.ja when needed
- Read the relevant source file
- Verify every selector targets elements/classes/IDs that exist in source CSS or browser.xhtml
- Verify every CSS variable override matches a variable defined in source
- Use variables over direct property overrides when the source uses variables
- Remove rules that match nothing
File placement
| Target | File | Selector scope |
|---|---|---|
| Browser chrome | userChrome.css |
:root, #navigator-toolbox, etc. |
| Web content pages | userContent.css |
@-moz-document rules |
| DevTools | userContent.css |
:root.theme-dark / :root.theme-light |
DevTools theming
Override DevTools variables in userContent.css using :root.theme-dark (or :root.theme-light).
- Do NOT use
@-moz-document url-prefix("chrome://devtools/content/")— doesn't match DevTools documents - Do NOT put DevTools overrides in userChrome.css — DevTools runs in a separate iframe
- Variables are in
chrome/devtools/skin/variables.css - Reference: one-monokai-firefox-devtools
Search mode indicators
Two systems exist. Hide both when removing the chip:
- Legacy:
#urlbar-search-mode-indicator— shown via#urlbar[searchmode] > .urlbar-input-container > #urlbar-search-mode-indicator - Scotch Bonnet:
#searchmode-switcher-chicklet— shown via#urlbar[searchmode] #searchmode-switcher-chicklet(gated behindbrowser.urlbar.scotchBonnet.enableOverrideorbrowser.urlbar.searchModeSwitcher.featureGate) - Related:
#urlbar-searchmode-switcher,#searchmode-switcher-title,#searchmode-switcher-close,#searchmode-switcher-dropmarker
When CSS doesn't work
Search online for working reference implementations before guessing. One working example beats ten theories. The MrOtherGuy/firefox-csshacks repo is the canonical reference for userChrome hacks.
Tabs below content
Use CSS grid on #main-window > body, NOT order / -moz-box-ordinal-group:
@media not -moz-pref("sidebar.verticalTabs") {
#main-window > body {
display: grid !important;
grid-template-rows: repeat(8, max-content) 1fr;
grid-auto-rows: auto;
}
#navigator-toolbox {
display: contents;
}
#main-window #browser {
grid-row: 9 / 10;
}
#TabsToolbar {
grid-row: 10 / 11;
}
.browser-toolbar {
background: inherit;
background-attachment: fixed;
}
}
Why:
order/-moz-box-ordinal-groupmoves the entire#navigator-toolbox— grid lets each toolbar land in its own row-moz-box-ordinal-groupis legacy XUL layout, actively being removeddisplay: contentson#navigator-toolboxis required so its children participate in the grid
Source: firefox-csshacks/chrome/tabs_below_content_v2.css
Hiding tabs with a single tab
Critical rules beyond just collapsing the tab:
#TabsToolbar {
min-height: 0px !important;
}
#tabbrowser-tabs,
#pinned-tabs-container,
#tabbrowser-arrowscrollbox {
min-height: 0 !important;
}
.accessibility-indicator,
.private-browsing-indicator {
height: unset !important;
}
.accessibility-indicator > hbox {
padding-block: 0 !important;
}
/* Match both :only-of-type AND attribute-based selectors for tab groups/hidden tabs */
.tabbrowser-tab:only-of-type,
.tabbrowser-tab[first-visible-tab="true"][last-visible-tab="true"] {
visibility: collapse !important;
min-height: 0 !important;
height: 0;
}
/* Contain periphery so it can't hold toolbar open */
#tabbrowser-arrowscrollbox-periphery,
#private-browsing-indicator-with-label,
#TabsToolbar > .titlebar-buttonbox-container {
contain: strict;
contain-intrinsic-height: 0px;
}
Why:
:only-of-typealone fails when tabs are hidden by extensions or tab groups —[first-visible-tab][last-visible-tab]covers those cases#pinned-tabs-containercan force minimum height even when all tabs collapse.accessibility-indicator,.private-browsing-indicator,.titlebar-buttonbox-container,#tabbrowser-arrowscrollbox-peripheryall hold the toolbar open withoutcontain: strict- These periphery elements are the most common cause of persistent gaps
Source: firefox-csshacks/chrome/hide_tabs_with_one_tab.css
Removing toolbox borders and separators
Three rules required — setting --chrome-content-separator-color: transparent alone is insufficient:
:root[sizemode="normal"] {
border-top: none !important;
}
#navigator-toolbox::after {
content: none !important;
}
#navigator-toolbox {
border-bottom: none !important;
}
The ::after pseudo-element on #navigator-toolbox draws a bottom border that CSS variables do not control.
Source: firefox-csshacks/chrome/hide_toolbox_top_bottom_borders.css
Tab background direct overrides
CSS variables like --tab-border-radius are not consumed by all internal tab styles. Apply direct overrides:
.tab-background {
border-radius: 0 !important;
box-shadow: none !important;
border-top: 0 !important;
outline: none !important;
}
Source: firefox-csshacks/chrome/non_floating_sharp_tabs.css
Preventing tab animation interference
Firefox's built-in tab animation system can fight visibility collapse:
#TabsToolbar {
will-change: unset !important;
transition: none !important;
opacity: 1 !important;
}
Source: firefox-csshacks/chrome/non_floating_sharp_tabs.css
Autohide entire toolbox
Hide all toolbars, show on hover or urlbar focus. Uses rotateX transform (GPU-accelerated, no layout shift):
#navigator-toolbox {
position: fixed !important;
width: 100vw;
z-index: 10 !important;
transition: transform 82ms ease-in-out 600ms !important;
transform: rotateX(89.9deg);
transform-origin: top;
opacity: 0;
}
#navigator-toolbox:is(:hover, :focus-within) {
transition-delay: 0ms !important;
transform: rotateX(0deg);
opacity: 1;
}
The #urlbar[popover] also needs separate hide/show since it's a popover:
#urlbar[popover] {
opacity: 0;
pointer-events: none;
transition:
transform 82ms ease-in-out 600ms,
opacity 0ms 682ms;
transform: translateY(
calc(0px - var(--tab-min-height) - var(--urlbar-container-height))
);
}
#urlbar-container > #urlbar[popover]:is([focused], [open]) {
opacity: 1;
pointer-events: auto;
transition-delay: 0ms;
transform: translateY(0);
}
Keep toolbox visible when any popup is open:
#mainPopupSet:has(> [panelopen]:not(#tab-preview-panel)) ~ #navigator-toolbox {
transition-delay: 0ms !important;
transform: rotateX(0deg);
opacity: 1;
}
Source: firefox-csshacks/chrome/autohide_toolbox.css
Autohide nav-bar only
Show nav-bar overlaid on tabs when urlbar is focused. Uses grid to stack toolbars:
:root:not([customizing]) #navigator-toolbox {
display: grid;
grid-template-rows: auto;
}
:root:not([customizing]) #navigator-toolbox > .browser-toolbar {
grid-area: 1/1;
}
:root[sessionrestored] #nav-bar:not([customizing]) {
transform: rotateX(89.9deg);
transition:
transform 67ms linear,
opacity 0ms linear 67ms !important;
opacity: 0;
z-index: 3;
}
:root[sessionrestored] #nav-bar:focus-within {
transform: rotateX(0deg);
opacity: 1;
transition-delay: 0ms, 0ms !important;
}
Source: firefox-csshacks/chrome/show_navbar_on_focus_only.css
Autohide tabs toolbar
Hides tabs toolbar, shows on hover. Uses negative margin + transition:
:root {
--uc-tabs-hide-animation-duration: 48ms;
--uc-tabs-hide-animation-delay: 200ms;
}
#TabsToolbar:not([customizing]) {
visibility: hidden;
position: relative;
z-index: 1;
transition:
visibility 0ms linear var(--uc-tabs-hide-animation-delay),
margin-bottom var(--uc-tabs-hide-animation-duration) ease-out
var(--uc-tabs-hide-animation-delay) !important;
}
#navigator-toolbox:has(> :is(#toolbar-menubar, #TabsToolbar):hover)
> #TabsToolbar {
visibility: visible;
margin-bottom: 0px;
transition-delay: 0ms, 0ms !important;
}
Source: firefox-csshacks/chrome/autohide_tabstoolbar_v2.css
Autohide bookmarks toolbar
Uses rotateX with configurable delay:
#PersonalToolbar {
--uc-bm-height: 20px;
--uc-bm-padding: 4px;
--uc-autohide-toolbar-delay: 600ms;
}
#PersonalToolbar:not([customizing]) {
position: relative;
margin-bottom: calc(-1px - var(--uc-bm-height) - 2 * var(--uc-bm-padding));
transform: rotateX(90deg);
transform-origin: top;
transition: transform 135ms linear var(--uc-autohide-toolbar-delay) !important;
z-index: 1;
}
#navigator-toolbox:hover > #PersonalToolbar {
transition-delay: 100ms !important;
transform: rotateX(0);
}
Source: firefox-csshacks/chrome/autohide_bookmarks_toolbar.css
Autohide sidebar
Collapses sidebar to narrow strip, expands on hover:
#sidebar-box {
--uc-sidebar-width: 40px;
--uc-sidebar-hover-width: 210px;
--uc-autohide-sidebar-delay: 600ms;
--uc-autohide-transition-duration: 115ms;
min-width: var(--uc-sidebar-width) !important;
width: var(--uc-sidebar-width) !important;
max-width: var(--uc-sidebar-width) !important;
z-index: 3;
position: relative;
}
#sidebar-header,
#sidebar {
transition: min-width var(--uc-autohide-transition-duration) linear
var(--uc-autohide-sidebar-delay) !important;
min-width: var(--uc-sidebar-width) !important;
will-change: min-width;
}
#sidebar-box:hover > #sidebar-header,
#sidebar-box:hover > #sidebar {
min-width: var(--uc-sidebar-hover-width) !important;
transition-delay: 0ms !important;
}
#sidebar-splitter {
display: none;
}
Source: firefox-csshacks/chrome/autohide_sidebar.css
Hide tabs toolbar entirely
For use with tree-style-tab or native vertical tabs. Moves window controls to nav-bar:
@media not -moz-pref("sidebar.verticalTabs") {
#TabsToolbar:not([customizing]) {
visibility: collapse;
}
:root[customtitlebar]
#toolbar-menubar:is([autohide=""], [autohide="true"])
~ #nav-bar {
> .titlebar-buttonbox-container {
display: flex !important;
}
:root[sizemode="normal"] & {
> .titlebar-spacer {
display: flex !important;
}
}
}
}
@media -moz-pref("sidebar.verticalTabs") {
#sidebar-launcher-splitter,
#sidebar-main {
visibility: collapse;
}
}
Source: firefox-csshacks/chrome/hide_tabs_toolbar_v2.css
Tabs on bottom (within toolbox)
Reorders TabsToolbar below nav-bar without moving below content. Uses order:
@media not -moz-pref("sidebar.verticalTabs") {
.global-notificationbox,
#tab-notification-deck,
#notifications-toolbar,
#TabsToolbar {
order: 1;
}
#TabsToolbar > :is(.titlebar-spacer, .titlebar-buttonbox-container) {
display: none;
}
:root[customtitlebar]
#toolbar-menubar:is([autohide=""], [autohide="true"], [collapsed])
~ #nav-bar {
> .titlebar-buttonbox-container {
display: flex !important;
}
}
}
Source: firefox-csshacks/chrome/tabs_on_bottom_v2.css
All toolbars below content
Moves entire toolbox below content. Uses display: contents + order:
#navigator-toolbox {
display: contents;
--uc-navbar-height: 40px;
}
#main-window > body > #browser,
.global-notificationbox,
#tab-notification-deck,
#notifications-toolbar,
#toolbar-menubar {
order: -1;
}
Urlbar breakout must flip direction when toolbars are below:
#urlbar[breakout][breakout-extend] {
display: flex !important;
flex-direction: column-reverse !important;
transform: translateY(calc(var(--urlbar-container-height) - 100%));
}
.urlbarView-body-inner {
border-top-style: none !important;
}
Source: firefox-csshacks/chrome/toolbars_below_content_v2.css
One-line toolbar (tabs + nav-bar side by side)
Uses CSS grid with fractional columns:
@media not -moz-pref("sidebar.verticalTabs") {
:root:not([chromehidden~="toolbar"]) #navigator-toolbox {
display: grid;
grid-template-columns: 6fr 4fr;
}
#toolbar-menubar,
#PersonalToolbar,
.global-notificationbox {
grid-column: 1/3;
}
#TabsToolbar,
#nav-bar {
grid-row: 2/3;
}
#nav-bar {
border-top: none !important;
}
}
Source: firefox-csshacks/chrome/oneline_toolbar.css
Combined tabs + nav-bar
Tabs share space with nav-bar using flex-wrap:
#navigator-toolbox {
display: flex;
flex-direction: row-reverse;
flex-wrap: wrap;
}
#nav-bar,
#PersonalToolbar {
flex-grow: 1000;
}
#urlbar-container {
min-width: 250px !important;
}
#urlbar[open]:focus-within {
min-width: var(--uc-urlbar-min-width, none) !important;
}
Source: firefox-csshacks/chrome/combined_tabs_and_main_toolbars.css
Vertical tabs (sidebar-style)
Uses position: absolute on #tabbrowser-tabs with margin on content:
:root:not([customizing]) {
--uc-vertical-tabs-width: 220px;
--uc-navbar-height: 40px;
}
#PersonalToolbar,
#main-window:not([inDOMFullscreen]) > body > #browser {
margin-left: var(--uc-vertical-tabs-width);
}
:root:not([customizing]) #tabbrowser-tabs {
position: absolute !important;
height: 100vh;
left: 0;
padding-top: var(--uc-navbar-height);
width: var(--uc-vertical-tabs-width);
background-color: var(--toolbar-bgcolor);
contain: size;
}
Source: firefox-csshacks/chrome/vertical_tabs.css
Multi-row tabs
Flexbox wrap with scroll:
:root {
--multirow-n-rows: 3;
--multirow-tab-min-width: 100px;
}
#tabbrowser-tabs[orient="horizontal"] {
min-height: unset !important;
flex-wrap: wrap;
overflow-y: auto;
overflow-x: hidden;
max-height: calc(
(var(--tab-min-height) + 2 * var(--tab-block-margin, 0px)) *
var(--multirow-n-rows)
);
scrollbar-width: thin;
scroll-snap-type: y mandatory;
}
.tabbrowser-tab {
scroll-snap-align: start;
}
#tabbrowser-tabs .tabbrowser-tab[pinned] {
position: static !important;
}
Tab reordering does not work with multi-row. Hide scroll buttons and spacer:
#scrollbutton-up,
#scrollbutton-down {
display: none;
}
#tabbrowser-arrowscrollbox > spacer {
display: none !important;
}
Source: firefox-csshacks/chrome/multi-row_tabs.css
Nav-bar below content
Uses position: fixed at bottom. Must use -webkit-box display (not flex) to avoid breaking extension menus:
#browser {
margin-bottom: var(--uc-bottom-toolbar-height, 0px);
}
#nav-bar {
position: fixed !important;
bottom: 0px;
display: -webkit-box;
width: 100%;
z-index: 1;
}
#nav-bar-customization-target {
-webkit-box-flex: 1;
}
Urlbar breakout flips upward:
#urlbar[breakout][breakout-extend] {
display: flex !important;
flex-direction: column-reverse !important;
bottom: 0px !important;
top: auto !important;
}
Source: firefox-csshacks/chrome/navbar_below_content.css
Floating findbar
Overlays findbar at top of content area instead of pushing content down:
findbar {
order: -1;
margin-bottom: -33px;
position: relative;
border-top: none !important;
padding: 0 !important;
background: none !important;
pointer-events: none;
z-index: 1;
}
findbar > .findbar-container,
findbar > .close-icon {
background-color: var(--lwt-accent-color, var(--toolbox-bgcolor)) !important;
pointer-events: auto;
border-bottom-right-radius: 4px;
}
findbar[hidden] {
transform: translateY(-30px);
}
Source: firefox-csshacks/chrome/floating_findbar_on_top.css
Overlay fullscreen toolbars
Toolbars float over content in fullscreen instead of pushing it down:
@media -moz-pref("browser.fullscreen.autohide") {
:root[sizemode="fullscreen"] #navigator-toolbox {
position: fixed !important;
width: 100vw;
z-index: 10 !important;
transition: transform 82ms ease-in-out 600ms !important;
transform: translateY(-100%);
}
:root[sizemode="fullscreen"] #navigator-toolbox:is(:hover, :focus-within) {
transition-delay: 0ms !important;
transform: translateY(0);
}
}
Source: firefox-csshacks/chrome/overlay_fullscreen_toolbars.css
Compact proton
Variables for compact density:
:root {
--toolbarbutton-inner-padding: 6px !important;
--tab-block-margin: 2px !important;
--tabs-shadow-size: 0px !important;
--arrowpanel-menuitem-padding-block: 5px !important;
--panel-font-size: inherit !important;
--arrowpanel-padding: 0.8em !important;
--tab-inline-padding: 8px !important;
}
#nav-bar {
box-shadow: inset 0 var(--tabs-shadow-size) 0 var(--lwt-tabs-border-color) !important;
}
.tab-close-button {
width: 20px !important;
height: 20px !important;
padding: 5px !important;
}
Source: firefox-csshacks/chrome/compact_proton.css
Compact urlbar
Prevents urlbar breakout expansion:
#urlbar[breakout][breakout-extend] {
margin-left: 0 !important;
width: var(--urlbar-width) !important;
margin-top: calc(
(var(--urlbar-container-height) - var(--urlbar-height)) / 2
) !important;
}
:where(#urlbar) > .urlbar-background,
#urlbar-background {
animation: none !important;
}
:where(#urlbar) > .urlbar-input-container {
padding: var(--urlbar-container-padding, 0) 1px !important;
height: var(--urlbar-height) !important;
}
Source: firefox-csshacks/chrome/compact_urlbar_megabar.css
Rounded menupopups
Rounding panels, menus, urlbar consistently:
:root {
--uc-menupopup-border-radius: 20px;
}
panel[type="autocomplete-richlistbox"],
menupopup,
.panel-arrowcontent {
-moz-appearance: none !important;
border-radius: var(--uc-menupopup-border-radius) !important;
overflow: clip !important;
}
/* Match urlbar and searchbar */
searchbar#searchbar,
:where(#urlbar) > .urlbar-background,
#urlbar-background {
border-radius: var(--uc-menupopup-border-radius) !important;
}
/* Fix panel arrow position */
panel[type="arrow"] {
margin-inline-end: calc(-10px - var(--uc-menupopup-border-radius)) !important;
}
.panel-arrow {
margin-inline: var(--uc-menupopup-border-radius) !important;
}
Source: firefox-csshacks/chrome/rounded_menupopups.css
Minimal toolbar buttons
Hide buttons as dots, reveal on hover using transform: scale(0):
toolbar .toolbarbutton-1 > * {
transform: scale(0);
transition: transform 82ms linear !important;
}
toolbar:hover .toolbarbutton-1 > * {
transform: scale(1);
}
/* Dot placeholder */
toolbar .toolbarbutton-1:not([open]) {
background-image: radial-gradient(
circle at center,
currentColor 0,
currentColor 10%,
transparent 15%
);
}
toolbar:hover .toolbarbutton-1 {
background-image: none;
}
Source: firefox-csshacks/chrome/minimal_toolbarbuttons_v3.css
Color variable template
Key variables for full theme override:
:root {
--arrowpanel-background: <color> !important;
--arrowpanel-border-color: <color> !important;
--arrowpanel-color: <color> !important;
--lwt-accent-color: <color> !important;
--toolbar-bgcolor: <color> !important;
--tab-selected-bgcolor: <color> !important;
--lwt-text-color: <color> !important;
--toolbarbutton-icon-fill: <color> !important;
--toolbar-field-background-color: <color> !important;
--toolbar-field-focus-background-color: <color> !important;
--toolbar-field-color: <color> !important;
--toolbar-field-focus-color: <color> !important;
--toolbar-field-border-color: <color> !important;
--toolbar-field-focus-border-color: <color> !important;
--lwt-sidebar-background-color: <color> !important;
--lwt-sidebar-text-color: <color> !important;
}
#navigator-toolbox {
--lwt-tabs-border-color: <color> !important;
}
#tabbrowser-tabs {
--lwt-tab-line-color: <color> !important;
}
#sidebar-box {
--sidebar-background-color: <color> !important;
}
Source: firefox-csshacks/chrome/color_variable_template.css
Linux GTK window controls patch
CSD buttons don't respect layout rules by default on Linux:
.titlebar-buttonbox {
align-items: stretch !important;
}
.titlebar-button {
-moz-appearance: none !important;
-moz-context-properties: fill, stroke, fill-opacity;
fill: currentColor;
padding: 4px 6px !important;
flex-grow: 1;
overflow: clip;
}
Source: firefox-csshacks/chrome/linux_gtk_window_control_patch.css
Window controls on left
Use @media -moz-pref("userchrome.force-window-controls-on-left.enabled"):
@media -moz-pref("userchrome.force-window-controls-on-left.enabled") {
#nav-bar > .titlebar-buttonbox-container {
order: -1 !important;
> .titlebar-buttonbox {
flex-direction: row-reverse;
}
}
}
Also detectable via (-moz-gtk-csd-reversed-placement) or (-moz-platform: macos).
-moz-pref() media queries
Firefox 133+ supports @media -moz-pref("pref.name") for conditional CSS based on about:config prefs. Used extensively by firefox-csshacks for toggleable features:
sidebar.verticalTabs— native vertical tabs enabledbrowser.fullscreen.autohide— fullscreen toolbar autohideuserchrome.*— custom user prefs for CSS feature toggles
Common mistakes
#idvs.class— check source (e.g..private-browsing-indicator-with-labelis a class, not an ID)- Shadow DOM parts (
scrollbutton-up,scrollbutton-down) are::part(), not IDs tabbare element doesn't match — use.tabbrowser-tab- Pseudo-elements (
::before,::after) — verify they exist in source before targeting - Border/separator overrides — find which element has the border (e.g.
.urlbarView-body-inner, not.urlbarView-body-outer) .searchbar-engine-one-off-itemis not inside#urlbar#context-sep-navigationis in browser.xhtml, not in CSS#pocket-button,#scrollbutton-up,#scrollbutton-downdo not exist in browser.xhtmlorder/-moz-box-ordinal-groupfor layout reordering — use CSS grid instead- Setting CSS variables without
!importantdirect overrides — internal styles may not consume the variable - Relying on
visibility: collapsewithout zeroingmin-heighton all child containers - Missing
contain: stricton periphery elements when collapsing toolbars — they hold height open - Adding
!importantto variables — variables are automatically applied,!importanton them is pointless - Duplicate
user_pref()lines in user.js — last one wins silently, remove duplicates - GNOME theme prefs (
gnomeTheme.*) conflict with custom tab positioning
More from knoopx/pi
podman
Manages containers, builds images, configures pods and networks with Podman. Use when running containers, creating Containerfiles, grouping services in pods, or managing container resources.
122jujutsu
Manages version control with Jujutsu (jj), including rebasing, conflict resolution, and Git interop. Use when tracking changes, navigating history, squashing/splitting commits, or pushing to Git remotes.
117nix-flakes
Creates reproducible builds, manages flake inputs, defines devShells, and builds packages with flake.nix. Use when initializing Nix projects, locking dependencies, or running nix build/develop commands.
54scraping
Fetches web pages, parses HTML with CSS selectors, calls REST APIs, and scrapes dynamic content. Use when extracting data from websites, querying JSON APIs, or automating browser interactions.
48jscpd
Finds duplicate code blocks and analyzes duplication metrics across files. Use when identifying copy-pasted code, measuring technical debt, or preparing for refactoring.
45yt-dlp
Downloads videos from YouTube and other sites using yt-dlp. Use when downloading videos, extracting metadata, or batch downloading multiple files.
42