Google Apps Dark Mode

Hybrid dark mode across Google's web apps. Auto-detects native dark theme per page and falls back to whole-page filter inversion when native dark is unavailable or absent on the active account.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

Author
John Neerdael
Daily installs
1
Total installs
3
Ratings
0 0 0
Version
0.3.2
Created
2026-05-04
Updated
2026-05-04
Size
16.7 KB
License
MIT
Applies to

Google Apps Dark Mode

A Tampermonkey userscript that delivers true dark mode across Google's web apps in two complementary modes, with automatic detection of which one to use:

  • Patch mode for Gmail/Calendar/Drive when the active Google account has native dark theme enabled — small CSS patches fill gaps (toasts, dialogs, Gemini sidebars). Brand colors preserved.
  • Filter mode for everything else (Docs, Sheets, Slides, Forms, Apps Script) and as a fallback for Gmail/Calendar/Drive on accounts that don't have native dark on — whole-page filter: invert(1) hue-rotate(180deg). Catches every surface, including canvas-rendered content.

The script reads the page's body background luminance after first paint to decide which mode to apply, so multi-account users automatically get the right behavior on each account without any configuration.

Silent, always-on, no UI.

Install

  1. Install Tampermonkey (Violentmonkey and Greasemonkey 4+ also work — the script uses only GM_addStyle).
  2. Open the Tampermonkey dashboard → "+" tab → paste the contents of darkmode.user.js → Save.
  3. Enable Google's native dark theme in:
    • Gmail: Settings → Themes → Dark
    • Calendar: Settings → Appearance → Dark
    • Drive: Settings → Appearance → Dark (or "Device default" with OS in dark mode)
  4. Reload any open Google tab.

Apps covered

Always filter mode (canvas-rendered or no usable native dark): | App | URL | |---|---| | Docs | docs.google.com/document | | Sheets | docs.google.com/spreadsheets, sheets.google.com | | Slides | docs.google.com/presentation | | Forms | docs.google.com/forms | | Vids | docs.google.com/videos | | Drawings | docs.google.com/drawings | | Apps Script | script.google.com |

Auto-detected (patch mode if native dark is on, filter mode otherwise):

Group Apps
Workspace Gmail, Calendar, Drive, Keep, Meet, Chat, Voice, Sites, Contacts, Photos, Classroom, Translate, Workspace Admin, Groups
Developer / admin Gemini, AI Studio, Cloud Console, Firebase Console, Search Console, Looker Studio, Analytics
Ads / commerce Google Ads, AdSense, Merchant Center
Search / info Google Search results, Trends, Scholar, News

How filter mode works

A single rule applies filter: invert(1) hue-rotate(180deg) to <html>. Every pixel rendered on the page is inverted, including content drawn inside <canvas> (which CSS otherwise can't reach — modern Docs and Sheets render their main editing surface as canvas).

To stop photos and videos from appearing as negatives, the script re-inverts media:

  • <img>, <video>, <iframe>, <embed>, <object>
  • <image> elements inside SVG (Slides and Docs render embedded photos this way)
  • Elements with inline background-image styles

Trade-offs

Filter mode preserves original colors of: photos, embedded videos, chart images, slide images, screenshots — anything rendered as a media element.

Filter mode shifts:

  • Google brand blue → orange-ish
  • Google red → cyan-ish
  • Any element drawn directly on canvas inherits the inverted color (charts, conditionally-formatted cells, drawn shapes in Slides)

This is the cost of catching every surface without per-class CSS maintenance. Google's class names are heavily obfuscated and change across deploys, so per-class targeting is not practical for true comprehensive coverage.

Uninstall

Tampermonkey dashboard → toggle the script off, or delete it.

Troubleshooting

A specific image looks inverted on a filter-mode app. It's probably rendered through a path the script doesn't yet recognize. Open DevTools, find the element, note its tag and class. Add a re-invert rule to FILTER_BASE in darkmode.user.js:

your.selector { filter: invert(1) hue-rotate(180deg) !important; }

A patch-mode surface (Gmail/Calendar/Drive dialog, popover) is still light. Google likely changed a class name. Open the element in DevTools, find a stable selector (prefer [role=...] or [aria-label=...] over generated classes), and add a rule to the relevant MODULES.gmail / MODULES.calendar / MODULES.drive block.

Disable one app while keeping others working. Each app's CSS is its own module string inside darkmode.user.js (MODULES.gmail, MODULES.calendar, etc.). Set the offending one to an empty string ` ` and reload.

Disable filter mode for an app. In dispatch(), change the app's classification from 'filter' to 'none'.

Files

  • darkmode.user.js — the userscript
  • docs/superpowers/specs/2026-05-04-google-dark-mode-userscript-design.md — original design (note: the design has since pivoted from per-class theming to filter mode for Docs/Sheets/Apps Script, see commit history)
  • docs/superpowers/plans/2026-05-04-google-dark-mode-userscript.md — original implementation plan