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

braille-radar

v0.1.1

Published

Braille dot-matrix radar (spider) charts for terminals — framework-free TypeScript

Downloads

29

Readme

braille-radar

Braille dot-matrix radar (spider) charts for terminals. Framework-free TypeScript — works with console.log, any TUI, or your own renderer. Zero runtime dependencies.

License Dependencies Node TypeScript

Gemma 4 26B-A4B (Q4 QAT)                            100K CONTEXT
158 days ago · MoE (25B / 4B) · Text and vision

                      INTELLIGENCE
                           26%
                          ⡠⠒⡗⠢⡀
                       ⣀⠔⠉  ⡇ ⠈⠑⢄⡀
        ACCURACY    ⢀⠤⠊   ⡠⠒⡗⠢⡀  ⠈⠢⢄     SPEED
       High (Q4)  ⡠⠒⠁  ⣀⠔⠉  ⡇ ⠈⠑⢄⡀  ⠑⠢⡀  ~26-31 tok/s
                ⠰⡫⠤⣀⣀⣀⣀⣀⡠⠤⠤⠤⢄⡀⡀  ⠈⠢⢄⣀⡠⠬⡳
                 ⢣  ⠈⢣⠑⠒⡴⠭⣀⡀⡇⣈⣑⠦⡔⠒⠉⡏  ⢠⠃
                 ⠈⡆  ⠸⡀ ⠸⡀ ⡰⠉⡀ ⡜  ⡸   ⡎
                  ⠸⡀  ⢇  ⢀⠎⠤⠤⠬⢶⠁ ⢠⠃  ⡜
                   ⢱  ⢸⡆⡠⠃     ⠱⡀⡎  ⢰⠁
                    ⢇ ⢀⠟⠒⠒⠒⠒⠒⠒⠒⠒⠚⢆ ⢀⠇
             MEMORY ⠘⣴⣁⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣱⡜  SPECULATION
    Tight (17.7 GB)                   None

In a real terminal the profile renders in bright cyan, the grid in dim slate, labels in light text, and details in muted gray.

Why

Terminals are a character grid, which normally caps chart resolution at one pixel per cell. This library packs a 2×4 grid of Unicode Braille dots into every cell, giving charts twice the horizontal and four times the vertical resolution — that's the classic dotted aesthetic you see above, with smooth diagonal lines instead of ASCII staircases.

  • Renderer-agnostic frames. Rendering returns rows of { text, tone } runs with semantic tones (profile, guide, label, detail). Color them with the bundled ANSI layer, or feed the runs to OpenTUI/Ink <span>s, HTML, or anything else.
  • Any axis count. The pentagon layout is the headline chart; the generic renderer handles 3+ axes with configurable rings, spokes, center, and radius.
  • Animated transitions. Eased (cubic ease-out) interpolation between profiles, including smooth retargeting while a transition is in flight.
  • Unassessed axes. A value of undefined keeps the label but draws no edge — no fake zeros.

Install

npm install braille-radar

Requires Node 20+. Works with Node, Bun, Deno, and bundlers.

Quick start

import { frameToString, renderPentagonRadar, type PentagonRadarAxes } from "braille-radar"

const axes: PentagonRadarAxes = [
  { value: 0.26, label: "INTELLIGENCE", detail: "26%" },
  { value: 0.32, label: "SPEED", detail: "~26-31 tok/s" },
  { value: 0, label: "SPECULATION", detail: "None" },
  { value: 0.74, label: "MEMORY", detail: "Tight (17.7 GB)" },
  { value: 0.62, label: "ACCURACY", detail: "High (Q4)" },
]

console.log(frameToString(renderPentagonRadar(axes)))

Axis values are normalized to [0, 1] (out-of-range values are clamped). Axis order runs clockwise from the top vertex.

Pentagon charts

renderPentagonRadar(axes, values?, columns?, rows?) renders the labeled five-axis chart at 56×15 by default.

import {
  pentagonRadarValues,
  renderPentagonRadar,
} from "braille-radar"

const values = pentagonRadarValues(axes) // clamped, extracted values
const frame = renderPentagonRadar(axes, values)

Animating between profiles

Transitions run over PENTAGON_RADAR_DURATION_MS (220 ms) with a cubic ease-out curve. Retargeting mid-flight continues from the currently displayed values, so rapid selection changes never jump:

import {
  pentagonRadarTransitionValues,
  retargetPentagonRadar,
  type PentagonRadarTransition,
} from "braille-radar"

let transition: PentagonRadarTransition | null = null

function selectProfile(next: PentagonRadarValues, now: number): void {
  const current = transition === null
    ? pentagonRadarValues(axes)
    : pentagonRadarTransitionValues(transition, now)
  transition = retargetPentagonRadar(current, next, transition, now)
}

function draw(now: number): void {
  const values = transition !== null
    ? pentagonRadarTransitionValues(transition, now)
    : undefined
  console.log(frameToString(renderPentagonRadar(axes, values)))
}

See examples/animate.ts for a complete 25 fps loop.

Generic N-axis charts

import { frameToString, generateRadarValues, renderRadar } from "braille-radar"

const values = generateRadarValues({
  seed: 7,            // deterministic demo data
  targetIndex: 3,
  pointCount: 6,      // any axis count >= 3
  valueRange: [0.3, 1],
})

console.log(frameToString(renderRadar(values, {
  columns: 44,
  rows: 16,
  guides: { ringCount: 4, spokes: false }, // or `false` to disable
  // center: { x: 44, y: 32 },            // dot coordinates, optional
  // radius: 30,                           // defaults to the largest that fits
})))

Output & colors

| Export | Purpose | |---|---| | frameToString(frame, palette?) | Flattens a frame into an ANSI-colored string | | frameToPlainText(frame) | Same, with no escape sequences | | defaultPalette, rgb, rgbHex | Dark-terminal palette and 24-bit color helpers |

import { defaultPalette, frameToString, rgbHex, type RadarPalette } from "braille-radar"

const palette: RadarPalette = {
  ...defaultPalette,
  profile: rgbHex("#e879f9"), // magenta profile
}

console.log(frameToString(frame, palette))

Palette entries are SGR escape sequences; an empty string emits no escape, so unstyled tones stay plain. Because consecutive same-tone runs are pre-merged, frames also compose well — zip rows of two charts to place them side by side (examples/profiles.ts).

API overview

Pentagon (src/pentagon.ts)

| Export | Purpose | |---|---| | renderPentagonRadar(axes, values?, columns?, rows?) | Labeled five-axis chart | | pentagonRadarValues(axes) | Extract and clamp axis values | | interpolatePentagonRadar(from, to, progress) | Eased interpolation | | retargetPentagonRadar(current, next, previous, now) | Start/restart a transition | | pentagonRadarTransitionValues(transition, now) | Values at a timestamp | | PENTAGON_RADAR_COLUMNS / _ROWS / _DURATION_MS | Defaults: 56×15, 220 ms |

Generic (src/radar.ts)

| Export | Purpose | |---|---| | renderRadar(values, options) | Any axis count ≥ 3, configurable geometry and guides | | renderRadarCells(values, options) | Low-level cell grid (individual Braille characters) | | radarRuns(frame) | Group cells into same-tone runs | | interpolateRadarValues(from, to, progress) | Linear interpolation | | generateRadarValues({ seed, targetIndex, pointCount, valueRange }) | Deterministic profiles for demos/tests |

Examples

| Command | Shows | |---|---| | npm run example:basic | Labeled pentagon, default palette | | npm run example:profiles | Two charts side by side, custom palettes | | npm run example:animate | Eased transitions between profiles (Ctrl+C to stop) | | npm run example:generic | 3/6/8-axis charts with varied guide configurations |

Development

npm install
npm test         # vitest
npm run typecheck
npm run build    # emit ESM + declarations to dist/

Tests cover exact-frame rendering across axis counts, guide variants, unassessed axes, clamping and input validation, eased transitions and mid-flight retargeting, ANSI output, and a golden-frame layout regression test.

Releasing

  1. Update version in package.json.
  2. Run the full checks: npm run typecheck && npm test && npm run build.
  3. Inspect the tarball: npm pack (runs prepack → build automatically).
  4. Publish: npm publish.

Attribution

This library was extracted from Magnitude, an AI coding agent platform, where it powers the local-model assessment radar in the CLI. The original implementation lives in cli/src/components/radar.ts and cli/src/components/pentagon-radar.ts.

Changes made during extraction: the Effect Option dependency was replaced with plain number | undefined values, tone names were unified, and the ANSI output layer (src/ansi.ts) was added so charts render without a TUI framework.

License

Apache-2.0 © Magnitude AI Inc.

This project continues the copyright of the repository it was extracted from.