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

@tayomi/termaid-ts

v0.8.3

Published

Mermaid diagrams drawn as Unicode art in the terminal. A TypeScript port of termaid by Fabio Souto, held to byte parity with it.

Readme

@tayomi/termaid-ts

Mermaid diagrams drawn as Unicode art in the terminal.

A TypeScript port of termaid by Fabio Souto, held to byte parity with it: the same source, the same width and the same theme produce the same bytes as the reference itself, colour codes included.

This is an unofficial port, not affiliated with the termaid project. See What this is a port of.

╭───────────╮
│           │
│   Idle    │◄──╮
│           │   │
╰─────┬─────╯   │
      │         │stop
 start│         │
      ▼         │
╭───────────╮   │
│           │   │
│  Running  ├───╯
│           │
╰───────────╯

Install

npm install @tayomi/termaid-ts

No runtime dependencies. Node 22 or later.

Use it as a library

import { render, renderThemedText, printToConsole } from "@tayomi/termaid-ts";

const source = "stateDiagram-v2\n  Idle --> Running : start\n";

// plain text
console.log(render(source, { width: 80 }));

// painted, folded to a console's width the way the reference's own console does
process.stdout.write(printToConsole(renderThemedText(source, { width: 80 }, "neon")));

render and renderThemedText take the same Options the command line exposes: width, useAscii, paddingX, paddingY, roundedEdges, gap. Every parser and every renderer is exported by name too, for a caller that wants one diagram kind without the dispatcher.

renderThemedText returns a Text, not a string: a painted drawing is a grid of styled cells, and folding it to a width is the console's job rather than the library's. renderThemed is the shortcut that paints and stringifies in one call, without folding.

background: "light" paints the drawing for a light terminal: every theme here was drawn for a dark one, and the pale foregrounds that read on black turn to fog on white. Each colour is mirrored about its luminance with its hue kept, at the single seam every colour crosses, so a theme's palette, a chart's section colours and a fill the source itself declared all turn together. The layout is untouched, and asking for dark or asking for nothing changes not one byte.

declaredType(source) names the diagram kind a source declares, or returns null where it declares none this renderer knows. A null source is not refused: like the reference, the dispatcher falls back to the flowchart parser and draws its lines as node labels. The export is a caller's chance to tell a type from a newer mermaid apart from a diagram, and to show the source instead.

Use it as a command

termaid diagram.mmd --width 100 --theme neon
echo 'graph LR; A-->B' | termaid
termaid --themes
termaid --demo

Colour follows the same rule the reference follows, which is Rich's: NO_COLOR silences everything, a dumb TERM silences it too, and what is left paints on a terminal alone or where FORCE_COLOR holds a non-empty value.

Diagram kinds

Flowchart, state, sequence, class, ER, gantt, git graph, journey, kanban, mindmap, packet, pie, quadrant, timeline, treemap, xy chart, architecture, block.

How parity is held

Three checks, and none of them trusts the other two.

| Command | What it answers | | --- | --- | | bun run compare | the port against takes of the reference frozen under fixtures/expected/ | | bun run differential | the port against the LIVE reference, on a deliberately hostile corpus of mutated sources | | bun run verify | the typecheck, the suite, and the takes this port answers for alone |

The frozen takes say what the reference drew the day the oracle ran, so a version bump invalidates all of them at once: bun run oracle writes them again. The differential harness is the one that catches what frozen takes cannot, since it feeds both sides truncated lines, unclosed delimiters, empty labels and arrows inside labels, and a port has to be wrong in exactly the same way as the reference.

A handful of drawings this port answers for ALONE, where the reference loses something its author wrote, sit under fixtures/divergences/ with takes written by bun run ourtakes. They are kept out of fixtures/ on purpose: the parity corpus feeds the mutants, so a divergence held there would spread across a whole family of them. Each one is argued in CHANGELOG.md under a ◉ and named in the differential's own allowance list.

The reference is the Python termaid itself, pinned and fetched from PyPI by uv: scripts/reference.ts names the version, and the two harnesses that spawn it need uvx on the machine. Nothing here is a dependency of the package, so installing it costs a consumer nothing.

What this is a port of

termaid is a Python tool by Fabio Souto, MIT licensed. It reads Mermaid and draws it in the terminal. This package is that tool rewritten in TypeScript, so a Node project can draw the same diagrams without spawning a Python process.

Three things are worth knowing about how the rewrite was done.

It is a port, not a reimplementation. The Python module tree is kept file for file, so parser/gantt.py is parser/gantt.ts and an upstream change names its own place here. Where CPython or Rich have a behaviour JavaScript does not, that behaviour is written out rather than approximated: pycompat.ts holds the CPython semantics the port leans on (banker's rounding, %g, str.center, code point ordering) and richcompat.ts holds the slice of Rich it depends on, down to Rich emitting one SGR sequence per character.

Parity is the specification, not an aspiration. The reference's own bytes are the only verdict: what termaid 0.8.0 draws is frozen under fixtures/expected/, and a fixture counts only once the port renders the same bytes. The version number tracks the reference it answers to: the major.minor names the termaid release the port reproduces, the patch counts this package's own additions on top of it, and CHANGELOG.md records those additions release by release. The upstream's own history stays upstream; that file is this repo's alone.

It is verified against the live reference, not only against frozen output. Frozen takes say what it drew on one day, for sources someone chose. The differential harness runs both implementations side by side on a hostile corpus, and it has already found things frozen takes could not: a case where the reference is non deterministic, and a malformed date format the port accepted where CPython refuses the whole render.

Not affiliated with the termaid project. MIT permits the derivative work and this package carries the original copyright notice; the name says what it is a port of, nothing more. See NOTICE.md.

What is not ported

--tui, the Textual interface, which has no equivalent here. The command reports that and exits.