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

ansispeck

v0.4.2

Published

ANSI that slips in and gets to work.

Readme

ansispeck

NPM JSR Socket

~2 KB (gzipped) terminal ANSI color formatting with explicit entrypoints.

Install

npm install ansispeck

Quick start

import { bold, green, red } from "ansispeck";

console.log(`${red("Error:")} ${bold(green("recovered"))}`);

The root import detects color support once when it loads. Its color and style functions emit ANSI when enabled and return plain text otherwise. For most programs, this is the only entrypoint you need.

Which entrypoint should I use?

| Import | API | Use it when | | ------------------------------- | ------------------------------------ | ------------------------------------------------------------- | | ansispeck or ansispeck/auto | Ordinary functions returning strings | You want colors that follow terminal and environment settings | | ansispeck/safe | Tagged templates returning strings | An enclosing style must survive interpolated or styled values | | ansispeck/rope | Composable chunks rendered later | You build large or deeply nested output before rendering it | | ansispeck/raw | Ordinary functions, always enabled | You need ANSI codes regardless of color detection | | ansispeck/noop | Ordinary functions, always disabled | You need guaranteed plain text |

The enabled ordinary formatters (auto and raw) already preserve styles when you nest function calls. The safe and rope entrypoints provide different ways to compose output when ordinary string functions are not the best fit.

Safe templates

ansispeck/safe exports template tags. When template text follows an interpolation, the outer style is restored first, even if the interpolated value contains ANSI close codes.

import { bold, red } from "ansispeck/safe";

const status = bold`OK`;
console.log(red`Status: ${status} - this remains red`);

Use template syntax with this entrypoint: red is a tag here, not a function called as red("text").

Rope composition

ansispeck/rope builds a chunk tree. Styling and concatenation add chunks without flattening the whole value; render creates the final string once at the end.

import { concat, dim, red, render } from "ansispeck/rope";

const line = concat(dim("12:34 "), red("ERROR"), " something broke");

console.log(render(line));

This is useful for deferred composition in hot paths such as log records, tables, and other output assembled from many pieces.

Rule of thumb

  • Formatting ordinary strings: use ansispeck.
  • Composing tagged templates with interpolated styles: use ansispeck/safe.
  • Building a large chunk tree to render once: use ansispeck/rope.
  • Requiring an unconditional mode: use ansispeck/raw, ansispeck/noop, or a factory with an explicit toggle.

Explicit control

Use a factory when detection is not what you want:

import { createColors } from "ansispeck";

const forced = createColors(true);
const plain = createColors(false);
const colorsWithoutLinks = createColors(true, false);

console.log(forced.red("always colored"));
console.log(plain.red("always plain"));
console.log(colorsWithoutLinks.link("https://example.com", "plain link text"));

createSafeColors from ansispeck/safe accepts separate color and hyperlink toggles. createRope from ansispeck/rope accepts a color toggle.

API

Ordinary color and style formatters accept strings, numbers, booleans, bigints, null, or undefined and return a string. Safe formatters are template tags, while rope formatters accept values or chunks and return a chunk.

Styles

reset bold dim italic underline inverse hidden strikethrough overline doubleUnderline blink

Colors

black red green yellow blue magenta cyan white gray/grey

Bright colors

blackBright redBright greenBright yellowBright blueBright magentaBright cyanBright whiteBright

Backgrounds

bgBlack bgRed bgGreen bgYellow bgBlue bgMagenta bgCyan bgWhite

Bright backgrounds

bgBlackBright bgRedBright bgGreenBright bgYellowBright bgBlueBright bgMagentaBright bgCyanBright bgWhiteBright

256-color and truecolor

import c from "ansispeck";

c.fg256(208)("orange"); // \x1b[38;5;208m
c.bg256(17)("navy background"); // \x1b[48;5;17m
c.rgb(255, 136, 0)("orange"); // \x1b[38;2;255;136;0m
c.bgRgb(0, 0, 0)("black background");
c.hex("#ff8800")("orange"); // #rgb and #rrggbb; # is optional
c.bgHex("#f80")("orange background");

Links

link(url, text?) creates an OSC 8 terminal hyperlink. It accepts a string or URL; when text is omitted, the URL is also used as the label. It can also be used as a template tag.

import { link } from "ansispeck";
import { pathToFileURL } from "node:url";

console.log(link("https://example.com", "docs"));
console.log(link(pathToFileURL("README.md"), "readme"));
console.log(link`https://example.com/issues/${42}`);

Hyperlink detection is independent of color detection. When links are disabled, link returns its label as plain text; without a label, it returns the URL.

Whitespace

space() and tab() return one space or tab. Pass a count to repeat it:

import { space, tab } from "ansispeck";

space(); // " "
space(4); // "    "
tab(2); // "\t\t"

Other exports

  • isColorSupported / isHyperlinkSupported - auto-detected booleans
  • detectColorSupport() / detectHyperlinkSupport() - run detection on demand
  • strip(input) - remove ANSI SGR and OSC sequences

Detection

Color respects NO_COLOR, FORCE_COLOR, --no-color, --color, CI, and TTY status. Explicit force (FORCE_COLOR/--color) beats explicit disable (NO_COLOR/--no-color), which beats platform heuristics.

Hyperlinks are detected separately, following the no-hyperlinks convention. Explicit --no-hyperlinks / --hyperlinks flags win first, then NO_HYPERLINKS, then FORCE_HYPERLINKS, then TTY status. Without an explicit override, non-interactive streams get no links.

Size

| Package | Runtime | Gzipped | Types | | ------------- | ----------- | ------- | -------- | | ansispeck[^1] | 5.54 KB | 2.44 KB | 15.83 KB |

[^1]: Default entry's full import chain (entry + shared chunks), minified by tsdown;
measured by scripts/compare-size.sh for the current benchmark snapshot.

Benchmarks

See BENCHMARKS for full results across Bun, Deno, and Node.

License

0BSD