claude-powerline re-resolves npx on every statusline render
Beautiful vim-style powerline for Claude Code
At a glance
- What is it?
- A statusline for Claude Code that reads git state, the model and session usage, installed either through a plugin wizard or by pasting a command into the settings file. The wizard writes the second of three config locations, the charset setting has no environment variable, the package ships its TypeScript sources, and the publish step lints and builds without running tests.
- Who is it for?
- claude-powerline is a small, well-documented piece of tooling, and the documentation quality is the thing that stands out. The git segment's two upstream options are explained independently, with the note that the default already gives you ahead and behind arrows without the branch name, and the exact flag to set to drop the arrows too.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 9, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Three identical npm badges and one plain http link
The badge row at the top of the readme carries four images. Three of them point at the same package page on the npm registry, and the fourth is a package size badge from a different service.
Three copies of the same badge is the kind of thing that happens when a template is copied and an extra badge is added without removing the originals, and it is worth noticing because it is a signal about how much of the page is maintained by hand.
The repository metadata tells a similar small story. The homepage field points at the GitHub readme, the repository field carries the usual git URL with the project name, and the description field is a sentence naming the style, the tracking, the git integration and the themes.
The declared homepage for the project is not on that list. It is a plain http address, not https, and the visual configurator linked two sections later uses the same scheme. Every other link on the page, including the plugin marketplace command that actually fetches the code, is https.
That is cosmetic rather than dangerous for a page that only renders images, but it is inconsistent, and for a project whose entire install path is a package manager fetching a statusline, the link that is supposed to be the canonical front door is the one with the weakest transport.
The wizard writes the second config file while a project file wins
There are three configuration locations, and the readme lists them in priority order. A file in the current directory is checked first, then a file under the user's Claude directory, then a file following the XDG convention.
The wizard writes to the second of those.
So a project that ships its own configuration file silently overrides everything the wizard just wrote, with no warning in either direction. The wizard will report success, the settings file is updated, and the segments you picked will not appear in that project.
The page does explain that configuration files reload automatically with no restart needed, which means the override takes effect immediately too, which makes the confusion faster rather than slower.
The priority order itself is stated separately from the file list, and it is a four-level chain: command line flags beat environment variables, which beat configuration files, which beat built-in defaults. So the same setting can be expressed in three places and the resolution is documented rather than discovered.
One small gap in the sample command. The documented way to fetch an example configuration writes it straight into the user's Claude directory with a download, without creating that directory first, so on a machine where it does not yet exist the command fails at the copy rather than at the download.
The manual path re-resolves the package on every render
The manual setup is a settings entry with one command in it:
{
"statusLine": {
"type": "command",
"command": "npx -y @owloops/claude-powerline@latest --style=powerline"
}
}The page explains the reasoning: npx downloads and runs the latest version without manual updates.
That reasoning trades a different problem for a smaller one. A statusline is invoked repeatedly, and each invocation goes through the package runner's resolution of a floating tag. The package is cached locally after the first fetch, so the download is a one-off, but the resolution is not, and a statusline that stalls while the runner checks is a statusline you notice.
There is also a consequence for reproducibility that the page does not mention. A floating tag means the version that renders today is not necessarily the version that rendered yesterday, with no changelog and no way to pin it short of replacing the tag with a version.
The flags tell you what the manual path gives you. One flag is passed, the style. The theme therefore takes its default, which is the dark one, and the charset takes its default, which is the Unicode one, so the documented manual setup produces a powerline with Unicode symbols and no font guarantee, on a machine where the page's own prerequisite section says you need a patched font.
The plugin path is different. It adds a marketplace, installs a named plugin, and runs a slash command inside Claude Code, and it is the one the page recommends.
Charset has no environment variable and no segment does
There are five environment variables, and what they cover is narrower than it first appears.
Four of them map onto settings you would expect to be adjustable from a shell: theme, style, a config path, and a debug switch. The fifth points at the usage cache location, which the readme gives a default for, inside the user's Claude directory.
There is no variable for the character set. That matters because the page's own advice for anyone without a patched font is to pass the text flag, and the only ways to set it are a command line flag or a configuration file. A user who keeps their settings in shell environment variables cannot set it there.
The same gap applies to the segments. Every git option, the directory style, the session type and the cost source are configuration-file only. So the reload-without-restart promise helps a file-based setup and does nothing for an environment-based one, and the four-level override chain has two of its four levels effectively unused by anyone who configures through the shell.
What is well handled is the session segment, which has four display formats and two cost sources. The calculated source is described as working the way a third-party usage tool does, and the official source as using hook data. Which one you are looking at changes whether the number is a reimplementation or something the editor reported, and the page says which is which rather than leaving you to guess from the digits.
Publishing lints, typechecks and builds without running the tests
The hook that runs before a publish is three commands in sequence: lint, typecheck, build.
There is no test step in it, even though the package has a test runner, a watch mode and a coverage mode configured, and a test script that the release workflow is otherwise able to call.
So the quality gate at the moment a version reaches the registry is a lint, a type check and a bundle. That is better than nothing and considerably worse than the four-step sequence it could be, since the test suite is the only one of the four that can catch a behaviour change rather than a shape change.
The build itself uses a different tool from the type check. The bundler is a newer-generation bundler configured by its own file, while the type check is the compiler in no-emit mode, and the tests run on a third framework with its own configuration file. Three tools across the three jobs, which is not unusual for a TypeScript package in 2026 but does mean a version bump has to move three dependency trees.
Two other small things in the same manifest. The Node type stubs are on a newer major than the engine floor the package declares, so code can typecheck against an API surface the minimum supported runtime does not have. And the published file list includes the source directory, not just the built output, which makes the tarball larger than the artifact needs to be and means the untranspiled code is part of what consumers install.
One git option is documented in prose and missing from the sample
The git segment's sample configuration has nine keys, and the option list beneath it describes ten.
The one described but not shown is the worktree indicator. The prose is precise about it: it shows an indicator when the current directory belongs to a linked git worktree, and its default is whatever the repository-name option is set to. So setting the repository name on gives you the worktree indicator as well, and turning the worktree indicator off on its own suppresses it while still showing the repository name.
That is a reasonable default, and it is the kind of coupling that is easy to miss when reading a list of booleans.
The rest of the segment is well specified. There are options for an abbreviated commit, staged and unstaged and untracked counts, in-progress operations like a merge or a rebase or a cherry-pick, the nearest tag, time since the last commit, a stash count, ahead and behind arrows, the upstream branch name, and the repository name. The arrows default to on and the upstream name defaults to off, and the page spells out the consequence: the default already gives you arrows without the name, and there is a specific flag to drop the arrows as well.
The directory segment has three path formats, from a complete path through a shell-style abbreviation to the folder name alone, and one automatic behaviour that needs no configuration: in a worktree session it shows the original repository path instead of the worktree folder.
Both charset variants are enumerated for every symbol, a Unicode set and a plain text set, which is what makes the text option actually usable rather than aspirational.
The main entry has no types and the package ships its sources
The manifest describes two entry points, and they are not symmetric.
The main entry is a single bundled file, and the package declares that file three times, as its main, as its module field and as its export map root. The module field is a legacy alias that most bundlers still read and that the export map has made unnecessary, so it is redundant rather than wrong.
The second entry is a browser build, and it is the only one with a types condition, pointing at a separate declaration file and a separate JavaScript file.
So the package root has no types condition at all. A consumer who imports the package in a typed project gets no declarations from the export map, and there is no top-level types field either. That is a real gap for a package whose only declared consumer is a statusline command that probably does not import it, which makes the library entry point more of a formality than an interface, and the asymmetry suggests the two entry points grew at different times.
The published file list is the other thing worth noting. It includes the built output, the command directory, the plugin directory, the source directory, the readme and the licence. Shipping sources is defensible for debugging and for tools that read a package's source map, and it does mean the tarball is substantially larger than the binary.
Publishing is configured for public access with provenance enabled, so a consumer can verify which build system produced the tarball. For a package whose documented install path fetches it over the network on demand, that is the more relevant trust signal than anything else in the manifest.
Editorial conclusion
claude-powerline is a small, well-documented piece of tooling, and the documentation quality is the thing that stands out. The git segment's two upstream options are explained independently, with the note that the default already gives you ahead and behind arrows without the branch name, and the exact flag to set to drop the arrows too. The worktree segment explains what happens in a linked worktree without needing configuration. Session usage has two cost sources with the difference named rather than implied, and the sample units option says outright that it does not apply to one of the four styles because that style already omits the suffix. That is documentation written by someone who has used it.
Three things to check before you install. The manual setup path runs the package through npx on every statusline render, which means a registry resolution at the frequency a statusline updates; the plugin path avoids that, and the wizard is the one the page recommends. The wizard writes your user config, but a project-level config file takes priority over it and there is no warning when one exists, so a project can silently override your choices. And the charset setting has no environment variable, so a user without a patched font has to pass it as a flag or set it in a config file rather than in their shell profile.
For the git segment, note that one option is described in prose but absent from the sample configuration, and its default is inherited from another option, so read both together before you assume turning one on does not turn on the other. Publishes carry a provenance attestation, which is worth having for a package that a statusline fetches over the network.
Frequently asked questions
How do I install claude-powerline for Claude Code?
Either run three commands inside Claude Code to add the marketplace, install the named plugin and run the slash command, or paste a statusLine entry into your settings file whose command runs the package through npx with a style flag. The wizard path writes your config file and updates settings automatically.
What does the claude-powerline status line show?
A configurable set of segments covering the current directory, git state including branch, status, tag, stash, ahead and behind, the model in use, and real-time session usage with four display formats and two cost sources.
Which config file wins in claude-powerline?
A file in the current project directory beats your user config, which beats the XDG location. Within that, command line flags beat environment variables, which beat config files, which beat built-in defaults. Config files reload without a restart.
Can I use claude-powerline without a Nerd Font?
Yes, by passing the text charset flag, which switches every symbol to a plain ASCII alternative. There is no environment variable for the charset, so it has to be set as a flag or in a config file.
What themes and styles does claude-powerline ship?
Six built-in themes, a dark one being the default, four styles with the minimal one as the default, and two character sets with the Unicode one as the default. A custom theme is also accepted, and there is a browser-based visual configurator for arranging segments.
What does claude-powerline need to run?
Node.js 18 or newer, Claude Code, and Git 2.0 or newer. A patched font is recommended for the Unicode symbol set, and the package manifest declares a Node engine floor of 18 with Node type stubs on a newer major.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/owloops-claude-powerline)