npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

hue-shift-cli

v1.2.1

Published

Give every VS Code project its own window colour. A Peacock alternative that runs from the terminal, with no extension.

Readme

hue-shift

CI npm license

Peacock colors one workspace. hue-shift colors all of them.

Give every VS Code project its own window colour from the terminal. No extension, no config file to hand-edit, no dependencies.

npx hue-shift-cli --random

hue-shift assigning a different colour to each project


Why not Peacock?

Peacock is great. It is also an extension, so it can only colour the workspace you are currently looking at. If you have 75 projects and want each one to look different, that is 75 manual actions.

hue-shift is a CLI. It walks your projects folder and writes the same workbench.colorCustomizations keys Peacock uses — so the two are compatible — but it does every project in one pass.

| | Peacock | Project Colors | Multi-Workspace | hue-shift | |---|---|---|---|---| | Runs from the terminal | ✗ | ✗ | ✗ | ✓ | | npx, nothing to install | ✗ | ✗ | ✗ | ✓ | | Colour all projects at once | ✗ | ✗ | ✗ | ✓ | | Detect drift (--check) | ✗ | ✗ | ✗ | ✓ | | Contrast validation | ✗ | ✗ | ✗ | ✓ | | Colour + theme + icons | ✗ | ✗ | theme only | ✓ | | Zero runtime dependencies | ✗ | ✗ | ✗ | ✓ | | Works on macOS, Linux, Windows | ✓ | ✓ | ✓ | ✓ |

Measured on an M1 Mac: 75 projects in 0.08 s, including reading and rewriting every settings.json. No build step, no daemon, no extension host.


Install

Nothing to install — run it directly:

npx hue-shift-cli --random

Or install it:

npm i -g hue-shift-cli          # global: gives you the `hue-shift` command
npm i -D hue-shift-cli          # per project, for npm scripts
bunx hue-shift-cli --random     # bun
pnpm dlx hue-shift-cli --random # pnpm

The package is hue-shift-cli because npm rejects hue-shift as too similar to an existing hueshift. Once installed, the command is still hue-shift.

Requires Node 18 or newer. Works anywhere that reads .vscode/settings.json: VS Code, Cursor, Windsurf, VSCodium.


Quick start

Colour the project you are standing in:

cd ~/code/my-app
npx hue-shift-cli --random

Colour every project under a folder, reproducibly:

npx hue-shift-cli --root ~/Documents/projects --random --seed 42

See what it would do before it does it:

npx hue-shift-cli --root ~/Documents/projects --random --seed 42 --dry

Pick a specific colour and only colour the title bar:

npx hue-shift-cli . --color amber --parts title

Colour plus a full theme and icon set:

npx hue-shift-cli . --color teal --theme "Default Dark Modern" --icons Seti

Reload the window (Cmd+Shift+P → Developer: Reload Window) and the colour appears.


Commands

hue-shift [project] [options]        one project (default: current directory)
hue-shift --root <dir> [options]     every subfolder of <dir> as a project

Colour

| Flag | What it does | |---|---| | --random | random colour per project (later --root runs only colour new projects) | | --seed <n> | make --random reproducible | | --color <hex\|name> | a specific colour | | --list-colors | print the built-in palette |

Appearance

| Flag | What it does | |---|---| | --parts <list> | title,activity,status,border,tab,sash,sidebar · default title,activity,status | | --adjust <part=mode> | lighten or darken per part, e.g. title=lighten,status=darken | | --adjust-pct <n> | how far to shift, default 6 | | --exclude <key> | never write this colour key (repeatable) | | --theme <name> | also set workbench.colorTheme | | --icons <name> | also set workbench.iconTheme |

Checks

| Flag | What it does | |---|---| | --check | report drift; writes nothing | | --reset | remove every colour key hue-shift wrote | | --restore | put settings.json back as it was before the first apply | | --dry | print the plan; writes nothing | | --json | machine-readable output |

Exit codes: 0 success, 1 usage error, 2 a project failed (including --restore with no backup).


Named palette

amber              #b45309     magenta            #a21caf
angular-red        #dd0531     mandalorian-blue   #1857a4
azure-blue         #007fff     node-green         #215732
burnt-orange       #c2410c     olive              #4d7c0f
crimson            #9f1239     peacock-blue       #0f4c81
cyan               #0e7490     react-blue         #61dafb
green              #15803d     rose               #be123c
javascript-yellow  #f9e64f     slate              #334155
                               svelte-orange      #ff3d00
                               teal               #0f766e
                               violet             #6d28d9
                               vue-green          #42b883

Every generated colour is checked against its foreground, so text on the title bar never drops below 4.5:1 contrast.

With --random, up to 16 projects get hues at least 22° apart, which keeps them clearly distinguishable. Beyond 16 the colour wheel cannot hold that gap, so hues spread as far apart as possible.


Config file

Pinned colours while you are away from the keyboard. hue-shift reads two files and merges them, project winning over global. CLI flags win over both.

~/.hue-shift.json — defaults for every project:

{
  "parts": ["title", "activity", "status"],
  "adjust": { "activity": "lighten" },
  "adjustPct": 6,
  "theme": "Default Dark Modern",
  "icons": "Seti"
}

<project>/.hue-shift.json — this project only:

{
  "color": "teal",
  "parts": ["title"],
  "exclude": ["statusBar.background"]
}

Fields: color, random, seed, parts, adjust, adjustPct, exclude, theme, icons.


What it writes

Only this block, and only the keys for the parts you asked for:

{
  "workbench.colorCustomizations": {
    "titleBar.activeBackground": "#b45309",
    "titleBar.activeForeground": "#ffffff",
    "titleBar.inactiveBackground": "#b45309cc",
    "titleBar.inactiveForeground": "#ffffff99",
    "activityBar.background": "#b45309",
    "activityBar.foreground": "#ffffff",
    "activityBar.inactiveForeground": "#ffffff88",
    "activityBar.activeBackground": "#b45309",
    "statusBar.background": "#b45309",
    "statusBar.foreground": "#ffffff",
    "statusBar.debuggingBackground": "#b45309",
    "statusBar.noFolderBackground": "#b45309"
  }
}

In --root mode it also writes hue-shift.lock.json in the root directory. The lock records each project's colour so later runs do not recolour projects that are already there.

Your settings.json is treated carefully:

  • Merged, not replaced. Colour keys hue-shift does not own are preserved.
  • Comments survive. JSONC // and /* */ outside the colour block are untouched.
  • BOM and CRLF survive. Windows line endings stay Windows line endings.
  • Peacock stays in sync. If peacock.color exists, it is updated to match.
  • --reset is exact. It removes only the keys listed above and leaves everything else.
  • --restore is exact. The first apply saves the original file to .vscode/.hue-shift-backup.json; restore writes it back byte for byte. If you commit .vscode, add .hue-shift-backup.json to .gitignore — it is a copy of your settings.

What it can't do

Honest limits, because a CLI is not an extension:

  • No status-bar colour chip. That needs the extension host.
  • No Live Share host/guest colours. Needs the VS Code API at runtime.
  • No "surprise me on startup". A CLI only runs when you run it.
  • No in-editor command palette entries. Use your terminal.

If you want those, run Peacock alongside. They write the same keys, so they do not fight.


Real workflow

Colours that stay put, with drift detection in CI:

# once, assign a palette and write the lock
cd ~/Documents/projects
npx hue-shift-cli --root . --random --seed 42

# later, after adding a project: existing colours stay put
npx hue-shift-cli --root . --random --seed 42

# fail a build when a project has drifted or has no colour
npx hue-shift-cli --root . --check

The first bulk run writes hue-shift.lock.json in the root. Later runs reuse those colours, so adding or removing folders never recolours an existing project. --seed only affects projects that are not in the lock yet. If the root is a git repository, commit the lock so a fresh clone gets the same palette. Delete it to re-roll every colour.

--check uses the lock as the expected palette and exits non-zero when a project has drifted or has no colour, so it works as a pre-commit or CI guard.


Examples

examples/ contains runnable scripts:

| File | Shows | |---|---| | basic.sh | one project, one colour | | bulk-seeded.sh | all projects, reproducible | | monorepo.sh | nested packages with a shared palette | | ci-drift.sh | fail a build when colours drift | | config-file/ | a pinned .hue-shift.json |


FAQ

Does it work alongside Peacock? Yes. Both write the same workbench.colorCustomizations keys. hue-shift also updates peacock.color if that setting exists, so Peacock does not fight back when it activates.

Will it overwrite my own colour customizations? No. It merges. Only the keys listed in What it writes are touched; anything else in workbench.colorCustomizations stays.

How do I undo it?

# revert settings.json to exactly what it was before the first apply
npx hue-shift-cli --root ~/projects --restore

# or just remove hue-shift's colour keys, keeping everything else
npx hue-shift-cli --root ~/projects --reset

--restore uses the one-time backup made before the first write. --reset is narrower: it removes only the keys hue-shift wrote, and leaves your other settings, comments, and line endings alone. Neither touches hue-shift.lock.json.

How do I re-roll all colours? Delete hue-shift.lock.json from the root and run the command again. To re-roll one project, remove its entry from the lock.

Why is the npm package called hue-shift-cli? npm rejects hue-shift as too similar to an existing hueshift package. The command it installs is still hue-shift.

Two projects got the same colour. Why? The wheel holds 16 hues at 22° apart. Past 16 projects the gap shrinks, and near-identical colours are possible. Use --color per project if you need exact control.

Do I have to run it every time I open a project? No. It writes to settings.json, which VS Code reads on startup. Run it once per project, or again when you add projects.

Does it work over SSH or in a remote window? Yes, if the remote machine's filesystem is where the project lives. Run it on the remote, not locally.

Does it touch anything outside .vscode/settings.json? It creates that file and directory if missing. On the first write it saves .vscode/.hue-shift-backup.json, which --restore uses. In --root mode it writes hue-shift.lock.json in the root. Nothing else.


Troubleshooting

The colour did not appear. Reload the window: Cmd+Shift+P → Developer: Reload Window. Settings are read at startup.

could not parse colorCustomizations. The colour block in that project's settings.json is malformed. Fix the JSON, or run --reset to remove the block entirely.

EACCES or permission denied. The settings file is owned by another user (common in Docker or sudo-created projects). Fix ownership, or run with the right user.

Text on the title bar is hard to read. hue-shift picks black or white text automatically and keeps contrast above 4.5:1. If a theme overrides it, add that key to exclude in .hue-shift.json.

Colours changed after a git pull. Someone committed a different settings.json. Re-run the same command with the same --seed to restore, and use --check in CI to catch it.


Development

git clone https://github.com/aotr/hue-shift.git
cd hue-shift
npm test

No dependencies to install. Tests use the built-in node:test runner.

src/colors.js     colour maths, palette, seeded random
src/lock.js       the stable --root palette
src/settings.js   JSONC-safe read / merge / write / reset / check
src/cli.js        argument parsing and the runner
bin/hue-shift.js  entry point

121 tests covering hex parsing, HSL round trips, contrast, JSONC edge cases, BOM/CRLF preservation, merging, reset/restore, the palette lock and every CLI flag.


Contributing

Bug reports, palette additions, and platform fixes are welcome. See CONTRIBUTING.md for the setup, the test commands, and what a good pull request looks like.

git clone https://github.com/aotr/hue-shift.git
cd hue-shift
npm test        # 121 tests, no install needed

License

MIT