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

funclaude

v1.0.0

Published

Replace Claude Code's spinner verbs with heists, felonies and supervillainy.

Downloads

152

Readme

funclaude

Claude Code shows a random verb while it works — Cogitating…, Noodling…, Reticulating….

funclaude swaps that list for something with a criminal record:

✻ Planting a bomb… (7s · esc to interrupt)
✻ Hijacking a car… (3s · esc to interrupt)
✻ Cracking the vault… (12s · esc to interrupt)

It is not a hack or a patch. Claude Code ships a supported setting for this.

The catch: two renderers, two config files

The terminal TUI and the VS Code panel draw their own spinners from different settings files. Writing only one is the single easiest way to conclude "it doesn't work":

| Where you see the spinner | Config file | Key | | --- | --- | --- | | Terminal CLI | ~/.claude/settings.json | spinnerVerbs | | VS Code / Cursor panel | <editor>/User/settings.json | claudeCode.spinnerVerbs |

The extension never reads ~/.claude/settings.json for verbs — its webview calls vscode.workspace.getConfiguration("claudeCode").get("spinnerVerbs").

funclaude writes every detected target by default, so this is invisible in normal use.

{ "mode": "replace", "verbs": ["Planting a bomb", "..."] }

mode: "replace" uses only your verbs; mode: "append" keeps the stock ones and adds yours. Claude Code appends the and the shimmer itself, so verbs are written bare.

Reload behaviour differs too. The VS Code panel watches its config (affectsConfiguration("claudeCode.spinnerVerbs")) and updates live. The terminal CLI caches settings in memory at startup and never re-reads them, so it needs a new session.

Install

Zero dependencies, Node 18+. Pick whichever fits the machine.

npx — nothing to install:

npx funclaude use mayhem heist

Global:

npm install -g funclaude
funclaude use mayhem heist

As a Claude Code plugin — adds a /funclaude command, and runs the bundled CLI directly via ${CLAUDE_PLUGIN_ROOT}, so it needs no npm at all:

/plugin marketplace add kaizenaiofficial2026/funclaude
/plugin install funclaude
/funclaude use mayhem heist

From a clone:

node bin/funclaude.js list        # run it in place
npm link                          # or put `funclaude` on your PATH

Use

funclaude list                    # browse the packs
funclaude preview mayhem          # watch it spin before committing
funclaude use mayhem heist        # apply one or more packs
funclaude use chaos --tips        # also replace the spinner tips
funclaude add "Defusing the bomb" # append your own
funclaude roll                    # sample what's currently active
funclaude status                  # what's set, and where
funclaude off                     # back to boring

The VS Code panel updates live. The terminal CLI needs a new session (see below).

The 18-character limit

Every verb is at most 18 characters, and funclaude add enforces it. This is not a style choice — it works around a real bug in the VS Code spinner.

The webview latches its render width on first mount and can never grow it:

let [text, setText] = useState(" ".repeat(width))   // width = maxVerbLength + 3
function writeChar(s, i, ch) { if (i >= s.length) return s; ... }   // refuses to extend

When a settings change arrives after the component mounts — exactly what a live config update does — the width is still the one derived from the default verb list. Its longest entry is Flibbertigibbeting (18 chars), giving a width of 21. Anything longer is silently chopped:

Distracting the receptionist  →  "Distracting the recep"
Walking away from the explosion  →  "Walking away from the"

Staying inside the stock maximum means our width requirement never exceeds the latched one, so truncation cannot happen regardless of mount timing. --force overrides the check if you only ever use the terminal CLI, which pads correctly.

Packs

| Pack | Vibe | Sample | | --- | --- | --- | | mayhem | Five-star wanted level | Planting a bomb… Hijacking a car… | | heist | Ocean's Eleven, minus the ten | Cracking the vault… Killing the lasers… | | villain | Volcano lair, excellent chair | Monologuing… Feeding sharks… | | spy | Trench coat, dead drop, trust issues | Going dark… Burning my cover… | | chaos | Deploying on Friday, confidently | Force-pushing main… Dropping the DB… | | wizard | Arcane, expensive, occasionally on fire | Sacrificing a goat… Rolling for init… | | pirate | Yarr, ship it | Plunderin' booty… Keelhaulin' a dev… | | corporate | The most terrifying pack available | Circling back… Boiling the ocean… |

Packs stack — funclaude use spy heist villain unions all three.

Flags

| Flag | Effect | | --- | --- | | --append | Keep Claude Code's defaults and add yours on top | | --tips | Also override the spinner tips — terminal CLI only, the webview has no tip rendering | | --cli | Only ~/.claude/settings.json | | --vscode | Only the editor's settings.json | | --project | ./.claude/settings.json instead of ~/.claude/settings.json | | --dry-run | Print the settings patch, change nothing | | --static | Preview without animation |

With no scope flag, every detected target is written. Editors are auto-detected across VS Code, Insiders, VSCodium, Cursor and Windsurf.

Project settings win over user settings, so --project lets one repo have its own theme.

Safety

Writes are a shallow merge — unrelated keys (theme, model, effortLevel, permissions, and your whole editor config) are left untouched. Every write drops a timestamped settings.json.funclaude-*.bak beside the original, and funclaude off removes only the keys this tool sets.

Editor settings.json files are JSONC. Comments survive reading but not rewriting, so if the target file has any, funclaude warns you and points at the backup.

Verify at any time with:

claude doctor    # reports "Invalid settings" if a settings file is malformed

Publishing

The repo serves both distribution paths from one tree:

.claude-plugin/plugin.json       plugin manifest
.claude-plugin/marketplace.json  single-entry marketplace, source "./"
commands/funclaude.md            the /funclaude slash command
bin/ lib/ package.json           the npm package

If you fork this, swap the owner handle in package.json, both manifests and this file:

grep -rl kaizenaiofficial2026 . --exclude-dir=.git \
  | xargs sed -i '' 's/kaizenaiofficial2026/<your-handle>/g'

To release:

claude plugin validate .claude-plugin/plugin.json       # both should pass
claude plugin validate .claude-plugin/marketplace.json
npm pack --dry-run                                      # inspect the tarball
npm publish                                             # needs `npm login`
git push -u origin main                                 # enables the plugin route

Bump version in both package.json and .claude-plugin/plugin.jsonclaude plugin tag checks that they agree.

Adding a pack

Add an entry to lib/themes.js:

noir: {
  label: 'Noir',
  blurb: 'It was raining. It is always raining.',
  emoji: '🚬',
  verbs: ['Lighting a smoke', 'Tailing the dame', 'Taking the case'],
  tips: ['Everybody lies.'],
},

Present participles, no trailing , 18 characters or fewer. That's the whole contract.