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

formatter-cli

v1.0.0

Published

A Node.js CLI tool for formatting CSS, HTML, JavaScript, and JSON — extracted from the Chrome DevTools frontend formatter worker.

Readme

formatter-cli

A standalone Node.js CLI that pretty-prints CSS, HTML, JavaScript and JSON. Formatting logic is ported directly from the Chrome DevTools frontend formatter_worker package, so the results match what you see in the DevTools Sources panel.

Install

cd formatter-cli
npm install
npm run build
# optionally link it globally
npm link

After npm link, the formatter-cli command is available anywhere on your machine.

Usage

# Format a file based on its extension (html / css / js / json)
formatter-cli index.html

# Force a language, choose indent width
formatter-cli -l json -i 2 package.json

# Read from stdin
curl -s https://example.com/style.css | formatter-cli -l css

# Format in-place
formatter-cli -l js -o script.js script.js

# CI check – exit 1 if the input is not already well-formed
formatter-cli --check -l html template.html

# With parse-error details
DEBUG=1 formatter-cli -l js broken.js

Options

| Flag | Description | | ----------------------- | ------------------------------------------------------------- | | [files...] | Files or glob patterns (e.g. src/**/*.js). Language auto-detected from extension. | | -l, --language <lang> | Force input language: css, html, js, json. | | -i, --indent <size> | Number of spaces per indent (default 4). | | -w, --write | Write formatted output back to each source file (in-place). | | --check | Dry run: exit non-zero if any file is not well-formatted. | | --color | Colorize diff-style output when --check reports mismatches. | | -h, --help | Show the usage banner. | | -V, --version | Print the version. |

Architecture

The port keeps the same module boundaries as the original DevTools code, with Node-only compatibility shims layered on top:

formatter-cli/
├── bin/formatter-cli.js            # shebang wrapper (ESM `import(...)`)
├── src/
│   ├── index.ts                 # CLI arg reader, stdin/stdout I/O
│   ├── platform/
│   │   ├── ArrayUtilities.ts    # lowerBound + DEFAULT_COMPARATOR
│   │   └── StringUtilities.ts   # findLineEndingIndexes, isWhitespace
│   ├── text-utils/
│   │   └── TextCursor.ts        # line/offset cursor
│   ├── codemirror/
│   │   └── register-codemirror.ts  # loads npm CodeMirror + modes
│   ├── types/
│   │   └── acorn-estree.d.ts    # augments `acorn` with `ESTree.Node`
│   └── formatter-worker/
│       ├── FormattedContentBuilder.ts   # output buffer / source-mapping
│       ├── FormatterActions.ts          # MIME type enum, FormatResult
│       ├── AcornTokenizer.ts            # peekable Acorn token wrapper
│       ├── ESTreeWalker.ts              # AST walker with parent pointers
│       ├── CSSFormatter.ts              # CSS formatter
│       ├── HTMLFormatter.ts             # HTML + embedded CSS/JS/JSON
│       ├── JavaScriptFormatter.ts       # JavaScript (Acorn-based)
│       ├── JSONFormatter.ts             # JSON
│       └── FormatterWorker.ts           # `format(mime, text, indent)` entry
├── package.json
└── tsconfig.json

Dependencies

  • codemirror@^5.65.16 — only the CommonJS CSS / XML / JavaScript / HTML-mixed mode packages plus the editor-core UMD IIFE for the CodeMirror global holder (getMode, startState, StringStream, defineMode…). The DOM-dependent editor pieces are never loaded; a tiny DOM stub is installed via register-codemirror.ts so the UMD wrapper can execute in Node.
  • acorn@^8.11.3 — the JS/ES parser consumed by JavaScriptFormatter.

DevTools-only types (@types/estree, @types/codemirror, @types/acorn, @types/node) are installed as devDependencies.

How it works — CodeMirror in Node

The original DevTools worker used an addon/runmode-standalone JS file that installed a DOM-free CodeMirror global, which the worker's mode-file ESM imports then attached to. The codemirror npm package ships only the CommonJS/UMD mode packages, whose UMD wrapper references the full DOM editor core during module evaluation (document.createElement, document.createRange, document.body, etc).

register-codemirror.ts pre-installs a minimal (and non-functional) DOM stub into globalThis long enough for those mode packages to load, at which point the codemirror IIFE populates globalThis.CodeMirror with the tokenizer-only subset that the formatter needs. This is exactly the same shape the DevTools worker relies on:

// original DevTools worker entrypoint
import '../../third_party/codemirror/package/addon/runmode/runmode-standalone.mjs';
import '../../third_party/codemirror/package/mode/css/css.mjs';
import '../../third_party/codemirror/package/mode/xml/xml.mjs';
import '../../third_party/codemirror/package/mode/javascript/javascript.mjs';

Becomes:

// formatter-cli/FormatterWorker.ts
import '../codemirror/register-codemirror.ts';
import 'codemirror/mode/css/css';
import 'codemirror/mode/xml/xml';
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/htmlmixed/htmlmixed';
const CodeMirror = globalThis.CodeMirror;

Scope and known limitations

This port covers the four public formatters that the DevTools worker exports via its format() entrypoint:

  • text/cssCSSFormatter
  • text/htmlHTMLFormatter
  • application/javascript / text/javascriptJavaScriptFormatter
  • application/jsonJSONFormatter

It does not include CSSRuleParser, ScopeParser or Substitute, which are unrelated to pretty-printing and only consumed by the DevTools debugger / styles sidebars. IdentityFormatter (used as a fallback for unknown media types) is implemented implicitly — unknown MIME types are returned untouched.

The DevTools build historically patched Acorn to permit a few non-standard patterns (e.g. the original ECMA_VERSION = 'latest' with allowImportExportEverywhere). This port uses the upstream Acorn 8 so a few legacy patterns (such as class private fields combined with top-level import/export under allowImportExportEverywhere at ecmaVersion:'latest') will instead surface as parse errors. The DevTools team's Acorn fork predates this port; users parsing unusual code should pin a specific acorn@<X> in their project if needed.

License

formatter-cli is BSD-3-Clause (matching the upstream DevTools license on the ported source files). The codemirror package is MIT.

Development

npm run dev          # watch mode (tsc -p tsconfig.json --watch)
npm run build        # one-shot build to ./dist
node bin/formatter-cli.js --help