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

@guml/highlight

v0.1.2

Published

Syntax highlighting for GUML. Pure TypeScript, no WebAssembly, runs during server rendering.

Downloads

356

Readme

@guml/highlight

Syntax highlighting for GUML. No WebAssembly, ~15 KB, zero runtime dependencies, and it runs synchronously — in a browser, in Node, and during server rendering.

pnpm add @guml/highlight
import { highlight, CLASS_STYLE } from "@guml/highlight";

const lines = highlight(`page "Counter"\nstate n: 0`, "guml");
// [
//   [ {text:"page", cls:"directive"}, {text:" ", cls:"plain"}, {text:"\"Counter\"", cls:"string"} ],
//   [ {text:"state", cls:"directive"}, …, {text:"0", cls:"number"} ],
// ]

One array per line, not a flat list — so you can render a line at a time without re-splitting, and line numbers come for free.

Each token carries cls, the compiler's own class name (tag, directive, modifier, string, number, binding, punct, prose, plain, …), not a CSS class. Map it to colour yourself, or use the CLASS_STYLE table this package ships:

{lines.map((toks, i) => (
  <div key={i}>
    {toks.map((t, j) => (
      <span key={j} className={CLASS_STYLE[t.cls]}>{t.text}</span>
    ))}
  </div>
))}

Why this exists separately from @guml/core

The compiler has its own classifier — guml_fmt::highlight, reachable as highlight() from @guml/core — and it is the authoritative one. Using it costs 787 KB of compiler WebAssembly, loaded asynchronously, in a browser.

Highlighting a code block needs none of that. It has to run synchronously during server rendering, and it has to work in Node, where the wasm build cannot load at all — it is compiled for the web target and loads itself with fetch().

So the trade is explicit:

| | @guml/highlight | @guml/core | |---|---|---| | size | ~15 KB | 787 KB wasm | | runtime | synchronous | async, after wasm init | | works in Node / SSR | yes | no | | authoritative | by parity test | by construction |

How it stays honest

A hand-written highlighter for a language whose vocabulary lives somewhere else is a drift machine. Two things stop that, and both are mechanical:

The vocabulary is generated. src/vocabulary.generated.ts comes from guml registry — the compiler's own tag, modifier and directive lists. A tag added in Rust reaches this package with no second edit. It is never retyped.

Tokenising is parity-tested. pnpm check:highlight runs this package and the compiler's Rust classifier over every fixture and fails on any disagreement. 936 spans across 10 documents currently agree.

Both halves earn their keep. The hand-maintained version of this file had already drifted before the checks existed — it listed h3, which the registry does not define — and the generator itself was emitting content-children: as a tag, because a section header in guml registry output matched the component pattern.

Other languages

tsx, bash, json and text are also supported, as ordinary regex grammars. Nothing in the compiler describes them, so there is nothing for them to drift from and no parity test to run.

highlight(source, "tsx");

Related


MIT.