# @speed-highlight/core

> A tiny, fast, simple syntax highlighter for the web and the terminal in JavaScript

Latest version **2.1.0** (published 2026-08-25) · CC0-1.0 license · 0 weekly downloads

## Install

```sh
npm install @speed-highlight/core
pnpm add @speed-highlight/core
yarn add @speed-highlight/core
bun add @speed-highlight/core
```

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 2.1.0 |
| Published | 2026-08-25 |
| First published | 2022-01-12 |
| Weekly downloads | 0 |
| License | CC0-1.0 |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 258.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 407 |
| Author | matubu |
| Maintainers | matubu |
| Keywords | javascript, syntax-highlighting, language, fast, js, simple, highlighter, regex, highlighting, highlightjs, small, deno |

## Links

- npm: https://www.npmjs.com/package/@speed-highlight/core
- Repository: https://github.com/speed-highlight/core
- Homepage: https://github.com/speed-highlight/core#readme
- Issues: https://github.com/speed-highlight/core/issues
- npm.io page: https://npm.io/package/@speed-highlight/core

## Alternatives

- [@mapbox/jsonlint-lines-primitives](https://npm.io/package/@mapbox/jsonlint-lines-primitives.md) — 5.3M weekly downloads
- [reftools](https://npm.io/package/reftools.md) — 3.5M weekly downloads
- [@hey-api/openapi-ts](https://npm.io/package/@hey-api/openapi-ts.md) — 3.5M weekly downloads
- [@mapbox/geojson-rewind](https://npm.io/package/@mapbox/geojson-rewind.md) — 2.4M weekly downloads
- [turbo-stream](https://npm.io/package/turbo-stream.md) — 1.7M weekly downloads

## Recent versions

- 2.1.0 (latest) — 2026-08-25
- 2.0.1 — 2026-08-24
- 2.0.0 — 2026-08-14
- 1.2.24 — 2026-08-09
- 1.2.23 — 2026-08-01
- 1.2.22 — 2026-08-01
- 1.2.21 — 2026-08-01
- 1.2.20 — 2026-08-01
- 1.2.19 — 2026-08-01
- 1.2.18 — 2026-08-01
- 1.2.17 — 2026-06-13
- 1.2.16 — 2026-06-09
- 1.2.15 — 2026-03-18
- 1.2.14 — 2025-12-29
- 1.2.12 — 2025-11-03
- … 22 more at https://npm.io/package/@speed-highlight/core/versions

## README

# speed-highlight

[![NPM Version](https://badge.fury.io/js/@speed-highlight%2Fcore.svg)](https://www.npmjs.com/package/@speed-highlight/core) [![NPM Downloads](https://img.shields.io/npm/dm/%40speed-highlight%2Fcore)](https://www.npmjs.com/package/@speed-highlight/core)

A tiny, fast, simple syntax highlighter for the web and the terminal in JavaScript

- **Tiny** (~1.5 kB gzipped core, ~1 kB gzipped per language)
- **Fast** (generally outperforms Prism and highlight.js, see the [benchmark](#benchmark))
- **Simple** (zero dependencies)

[**Playground**](https://speed-highlight.github.io)

![Screenshot](https://raw.githubusercontent.com/speed-highlight/core/main/assets/screenshot.png)

<!-- AUTOGENERATED:TOC:START (run `npm run build` to regenerate) -->
* [Quick start](#quick-start)
* [How it works](#how-it-works)
* [Comparison](#comparison)
* [Web usage](#web-usage)
	* [In a component](#in-a-component)
	* [On a plain page](#on-a-plain-page)
	* [Detect the language](#detect-the-language)
	* [Control loading and bundling](#control-loading-and-bundling)
	* [CDN (no build step)](#cdn-no-build-step)
* [Terminal usage](#terminal-usage)
* [API](#api)
* [Languages](#languages)
* [Themes](#themes)
* [Custom languages](#custom-languages)
* [Custom themes](#custom-themes)
* [Migrating from v1](#migrating-from-v1)
* [Benchmark](#benchmark)
<!-- AUTOGENERATED:TOC:END -->

## Quick start

```bash
npm i @speed-highlight/core
```

In a terminal, print the highlighted string:

```js
import { highlightANSI } from '@speed-highlight/core';
import theme from '@speed-highlight/core/themes/default.js';

console.log(await highlightANSI('console.log("hello")', 'js', theme));
```

In a component, highlight a string and render it:

```jsx
import { useEffect, useState } from 'react';
import { highlightHTML } from '@speed-highlight/core';
import '@speed-highlight/core/themes/default.css';

export function Code({ code, lang }) {
	const [html, setHtml] = useState('');

	useEffect(() => {
		// highlightHTML is async (languages load on first use), skip stale results
		let stale = false;
		highlightHTML(code, lang).then(result => { if (!stale) setHtml(result); });
		return () => { stale = true; };
	}, [code, lang]);

	return <div className={`shj-lang-${lang} shj-block`} dangerouslySetInnerHTML={{ __html: html }} />;
}
```

## How it works

The tokenizer runs a language's regex rules over your code and emits typed tokens (`kwd`, `str`, `cmnt`, ...). On the web each token becomes a `<span class="shj-syn-kwd">`; in the terminal it becomes an ANSI escape code. A theme is just CSS (or a token-to-escape map) coloring those names, which is why themes are under 1 kB and writing your own is a few lines.

## Comparison

Highlighters trade size for grammar fidelity: TextMate engines (Shiki, starry-night) are the most faithful and heaviest, mature regex engines (highlight.js, Prism) sit in the middle, lightweight regex tokenizers (speed-highlight, sugar-high) are the smallest and approximate on exotic syntax.

| | Core (gzip) | Per language (gzip) | Languages | Grammar model | Terminal | Status | Choose it for |
| --- | --- | --- | --- | --- | --- | --- | --- |
| speed-highlight | 1.5 kB | 0.07–1.6 kB | ~30 | lightweight regex | ✅ built in | ✅ v2 (this repo) | runtime highlighting where size and startup matter |
| [sugar-high](https://github.com/huozhi/sugar-high) | 1.7 kB | 0.18–2.9 kB | 25 | lightweight regex | ❌ | ✅ v2.0.0 | CSS-variable theming, JSX/TSX-aware JavaScript |
| [Prism](https://prismjs.com) | 3.1 kB | 0.3–3 kB | ~290 | mature regex | ❌ | ⚠️ v1.30.0, frozen since Mar 2025 (v2 rewrite) | its plugin ecosystem |
| [highlight.js](https://highlightjs.org) | 8.3 kB | 0.3–2.5 kB | ~190 | mature regex | ❌ (via wrappers) | ✅ v11.11 (Jun 2026) | broad auto-detection and rare languages |
| [Shiki](https://shiki.style) | 35 kB + engine: 145 kB WASM or 20 kB JS | 5–16 kB | ~220 | TextMate (VS Code) | ✅ via `@shikijs/cli` | ✅ v4.4, very active | highest fidelity (the same grammars as VS Code); zero client JS when run at build time |
| [starry-night](https://github.com/wooorm/starry-night) | 185 kB incl. WASM | 3–25 kB | 600+ | TextMate (GitHub) | ❌ | ✅ active | GitHub-identical rendering in Node |

Sizes are min+gzip, measured from the installed packages at the versions shown (per-language = range over the benchmark corpus; starry-night figures from its own README). Wrappers reuse these engines and inherit their numbers: lowlight/refractor wrap highlight.js/Prism for virtual DOMs, rehype-pretty-code and bright wrap Shiki, and the terminal-only [emphasize](https://github.com/wooorm/emphasize) and [cli-highlight](https://github.com/felixfbecker/cli-highlight) wrap highlight.js grammars into ANSI. Editors (CodeMirror, Monaco, tree-sitter) are a different category.

If you highlight at build time and bytes do not matter, use Shiki. speed-highlight's case is the opposite one: highlighting at runtime, where the entire library with all 34 grammars bundled into one file gzips to 9.0 kB, barely more than highlight.js's core alone, before it has loaded a single grammar.

## Web usage

### In a component

Frameworks own their DOM, so highlight the *string* and render it, as in the quick start (mutating a mounted node with `highlightElement` gets wiped on the next render). The output is HTML-escaped (`&`, `<`, `>`), safe to inject even for untrusted code; the `shj-lang-*` and `shj-block` classes hook it into the theme. The same pattern works in Vue, Svelte, and Angular; ready-made components are in [#85](https://github.com/speed-highlight/core/pull/85).

### On a plain page

Mark code blocks with a `shj-lang-*` class and call `highlightAll` once:

```html
<div class="shj-lang-js">console.log('hello')</div>
<code class="shj-lang-js">inline code</code>

<script type="module">
	import { highlightAll } from '@speed-highlight/core';
	highlightAll();
</script>
```

Blocks are a single `<div>` instead of `<pre><code>` so the line-number gutter can be laid out inside; the `shj-lang-` prefix avoids colliding with Prism's `language-*` during a migration.

For per-element control use `highlightElement`. It renders a `code` element inline and anything else as a block, accepts `block` as an override, and sets `data-lang` so a theme can render a language header with `content: attr(data-lang)`:

```js
import { highlightElement } from '@speed-highlight/core';

await highlightElement(element, 'js', { showLineNumbers: true });
```

### Detect the language

Detection is a separate ~1 kB import so the core stays small. It recognizes about 20 common languages and returns `'plain'` when unsure:

```js
import { highlightElement } from '@speed-highlight/core';
import { detectLanguage } from '@speed-highlight/core/detect';

element.textContent = code;
await highlightElement(element, detectLanguage(code));
```

### Control loading and bundling

Languages load lazily through a loader. Replace it with `setLoader` to add custom languages or restrict what your bundler includes; a name the loader cannot resolve renders as plain text:

```js
import { setLoader, defaultLoader } from '@speed-highlight/core';

// add custom languages on top of the bundled ones
setLoader(name => customs[name] ?? defaultLoader(name));

// or allow only the languages your bundler can code-split
setLoader(name => ({
	js: () => import('@speed-highlight/core/languages/js.js'),
	css: () => import('@speed-highlight/core/languages/css.js'),
})[name]?.());
```

For full tree-shaking skip the loader entirely: `tokenizeWith` takes every language from the caller, so a bundler keeps only what you import. Include the sub-languages a grammar embeds (`html` uses `css` and `js`; `js` uses `jsdoc`, `todo`, and `regex`). A sub that is not given keeps the type of its rule and only skips the inner highlighting:

```js
import { tokenizeWith } from '@speed-highlight/core/tokenize';
import { html, css, js, jsdoc, todo, regex } from '@speed-highlight/core/languages';

tokenizeWith(code, html, (str, type) => { /* ... */ }, { languages: { css, js, jsdoc, todo, regex } });
```

> [!NOTE]
> `highlightHTML` and `tokenizeWith` never touch the DOM, so they also run server-side or in a web worker: highlight there and send the string over.

### CDN (no build step)

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@speed-highlight/core@2/dist/themes/default.css">
<script type="module">
	import { highlightAll } from 'https://cdn.jsdelivr.net/npm/@speed-highlight/core@2/dist/index.js';
	highlightAll();
</script>
```

## Terminal usage

`highlightANSI` returns a string ready to print; the theme is required, import one from `themes/*.js`:

```js
import { highlightANSI } from '@speed-highlight/core';
import theme from '@speed-highlight/core/themes/atom-dark.js';

console.log(await highlightANSI(code, 'js', theme));
```

A terminal theme is a plain token-to-escape map, built with the `termcolor` helpers or raw escapes:

```js
import * as col from '@speed-highlight/core/themes/termcolor.js';

export default {
	kwd: col.red,
	str: col.green,
	cmnt: col.gray,
};
```

For Deno, use the [deno module](https://deno.land/x/speed_highlight_js):

```js
import { highlightANSI } from 'https://deno.land/x/speed_highlight_js/dist/index.js';
import theme from 'https://deno.land/x/speed_highlight_js/dist/themes/default.js';

console.log(await highlightANSI('console.log("hello")', 'js', theme));
```

## API

The main entry covers most apps; reach for `/tokenize` when you want the raw token stream and full control over what gets bundled. Everything ships TypeScript types.

| Entry | Export | Description |
| --- | --- | --- |
| [`@speed-highlight/core`](src/index.js) | `highlightAll(opt?)` | Highlight every element with a `shj-lang-*` class |
| | `highlightElement(elm, lang?, opt?)` | Highlight one element (language read from its class by default) |
| | `highlightHTML(src, lang, opt?)` | Highlight a string, resolves to an HTML string |
| | `highlightANSI(src, lang, theme)` | Highlight a string, resolves to an ANSI string for terminals |
| | `tokenize(src, lang, onToken)` | Loader-based tokenizer, calls `onToken(text, type)` |
| | `setLoader(loader)` / `defaultLoader` | Replace or compose how language names are resolved |
| [`.../detect`](src/detect.js) | `detectLanguage(code)` | Guess the language, `'plain'` when unsure |
| [`.../tokenize`](src/tokenize.js) | `tokenizeWith(src, lang, onToken, opt?)`, `tokenizer` | Registry-free synchronous tokenizer (and the underlying generator), languages passed by the caller |
| [`.../languages`](src/languages/) | one named export per language | Grammars, import only what you need |
| [`.../themes/*.css`](src/themes/) | | Web themes |
| [`.../themes/*.js`](src/themes/) | | Terminal themes, plus `termcolor.js` helpers |

`lang` is a name (`'js'`) or a grammar object passed directly. `opt` is `{ block?: boolean, showLineNumbers?: boolean }`: line numbers are opt-in, `block` defaults to `true`, except that `highlightElement` and `highlightAll` read it off the element instead, where a `code` element is inline and anything else is a block.

## Languages

<!-- AUTOGENERATED:LANGUAGES:START (run `npm run build` to regenerate) -->
| Name | [CSS Class](#web-usage) | Support | Detection | Size (gzip, 14.4 kB total) |
| --- | --- | --- | --- | --- |
| Assembly | `shj-lang-asm` |  | ✅ | [`194 B`](src/languages/asm.js) |
| Bash | `shj-lang-bash` |  | ✅ | [`430 B`](src/languages/bash.js) |
| Brainfuck | `shj-lang-bf` | increment, operator, print, comment | ❌ | [`137 B`](src/languages/bf.js) |
| C | `shj-lang-c` |  | ✅ | [`429 B`](src/languages/c.js) |
| CSS | `shj-lang-css` | comment, str, selector, units, function, ... | ✅ | [`332 B`](src/languages/css.js) |
| CSV | `shj-lang-csv` | punctuation, ... | ❌ | [`96 B`](src/languages/csv.js) |
| Diff | `shj-lang-diff` |  | ✅ | [`144 B`](src/languages/diff.js) |
| Dockerfile | `shj-lang-docker` |  | ✅ | [`566 B`](src/languages/docker.js) |
| Git | `shj-lang-git` | comment, insert, deleted, string, ... | ❌ | [`222 B`](src/languages/git.js) |
| Go | `shj-lang-go` |  | ✅ | [`329 B`](src/languages/go.js) |
| HTML | `shj-lang-html` | inline style and event handlers | ✅ | [`726 B`](src/languages/html.js) |
| HTTP | `shj-lang-http` | keywork, string, punctuation, variable, version | ✅ | [`986 B`](src/languages/http.js) |
| INI | `shj-lang-ini` |  | ❌ | [`158 B`](src/languages/ini.js) |
| Java | `shj-lang-java` |  | ✅ | [`457 B`](src/languages/java.js) |
| JavaScript | `shj-lang-js` | basic syntax, regex, jsdoc, json, template literals | ⛔ reported as TypeScript | [`820 B`](src/languages/js.js) |
| JSDoc | `shj-lang-jsdoc` |  | ❌ | [`251 B`](src/languages/jsdoc.js) |
| JSON | `shj-lang-json` | string, number, bool, ... | ❌ | [`172 B`](src/languages/json.js) |
| LeanPub Markdown | `shj-lang-leanpub-md` |  | ❌ | [`1.2 kB`](src/languages/leanpub-md.js) |
| Log | `shj-lang-log` | number, string, comment, errors | ❌ | [`223 B`](src/languages/log.js) |
| Lua | `shj-lang-lua` |  | ✅ | [`273 B`](src/languages/lua.js) |
| Makefile | `shj-lang-make` |  | ✅ | [`223 B`](src/languages/make.js) |
| Markdown | `shj-lang-md` |  | ✅ | [`1.1 kB`](src/languages/md.js) |
| Perl | `shj-lang-pl` |  | ✅ | [`329 B`](src/languages/pl.js) |
| Plain text | `shj-lang-plain` |  | ❌ | [`71 B`](src/languages/plain.js) |
| Python | `shj-lang-py` |  | ✅ | [`416 B`](src/languages/py.js) |
| Regex | `shj-lang-regex` | count, set, ... | ❌ | [`176 B`](src/languages/regex.js) |
| Rust | `shj-lang-rs` |  | ✅ | [`414 B`](src/languages/rs.js) |
| SQL | `shj-lang-sql` | number, string, function, ... | ✅ | [`1.7 kB`](src/languages/sql.js) |
| TODO | `shj-lang-todo` |  | ❌ | [`185 B`](src/languages/todo.js) |
| TOML | `shj-lang-toml` | comment, table, string, bool, variable | ❌ | [`236 B`](src/languages/toml.js) |
| TypeScript | `shj-lang-ts` | js syntax, ts keyword, types | ✅ | [`911 B`](src/languages/ts.js) |
| URI | `shj-lang-uri` |  | ✅ | [`176 B`](src/languages/uri.js) |
| XML | `shj-lang-xml` |  | ✅ | [`511 B`](src/languages/xml.js) |
| YAML | `shj-lang-yaml` | comment, numbers, variable, string, bool | ✅ | [`208 B`](src/languages/yaml.js) |
<!-- AUTOGENERATED:LANGUAGES:END -->

## Themes

<!-- AUTOGENERATED:THEMES:START (run `npm run build` to regenerate) -->
| Name | Terminal (gzip) | Web (gzip) |
| --- | --- | --- |
| `default` | ✅ [`174 B`](src/themes/default.js) | ✅ [`603 B`](src/themes/default.css) |
| `atom-dark` | ✅ [`174 B`](src/themes/atom-dark.js) | ✅ [`699 B`](src/themes/atom-dark.css) |
| `dark` | ❌ | ✅ [`695 B`](src/themes/dark.css) |
| `github-dark` | ❌ | ✅ [`691 B`](src/themes/github-dark.css) |
| `github-dim` | ❌ | ✅ [`700 B`](src/themes/github-dim.css) |
| `github-light` | ❌ | ✅ [`672 B`](src/themes/github-light.css) |
| `visual-studio-dark` | ❌ | ✅ [`694 B`](src/themes/visual-studio-dark.css) |
<!-- AUTOGENERATED:THEMES:END -->

## Custom languages

A language is an array of rules. Every rule's regex (global flag required) is tried; the earliest match in the string wins, ties go to the earlier rule:

```js
export default [
	{ match: /\/\/.*/g, type: 'cmnt' },
	{ expand: 'str' },
	{ expand: 'num' },
	{ match: /\b(if|else|for|while|return)\b/g, type: 'kwd' },
];
```

- `{ match, type }` tags what the regex matches with a token type
- `{ expand }` reuses a shared pattern: `'num'`, `'str'`, or `'strDouble'`
- `{ match, sub }` re-tokenizes the matched region with another language: a name (loaded through the loader), an inline grammar array, or a function `code => name | grammar` deciding per match

A language can also set a default token for unmatched text by exporting `{ type, sub }` instead of a bare array (see [`http.js`](src/languages/http.js)). Use a grammar by passing it directly as `lang`, or register a name with `setLoader`. To extend an existing language, spread it after your rules:

```js
import js from '@speed-highlight/core/languages/js.js';

export default [
	{ match: /\b(signal|effect)\b/g, type: 'func' },
	...js,
];
```

Token types:

| Token | Used for | | Token | Used for | | Token | Used for |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `kwd` | keywords | | `type` | types | | `esc` | escape sequences |
| `str` | strings | | `class` | classes | | `section` | section delimiters |
| `num` | numbers | | `var` | variables | | `insert` | inserted parts (diff) |
| `cmnt` | comments | | `oper` | operators | | `deleted` | deleted parts (diff) |
| `func` | functions | | `bool` | booleans | | `err` | errors |

Missing a language? [Open an issue](https://github.com/speed-highlight/core/issues) or send a PR adding a file to [`src/languages/`](src/languages/).

## Custom themes

A web theme colors the token classes; start from [`default.css`](src/themes/default.css) and override:

```css
[class*="shj-lang-"] { color: #f8f8f2; background: #282a36; }
.shj-syn-kwd { color: #ff79c6; }
.shj-syn-str, .shj-syn-insert { color: #50fa7b; }
.shj-syn-cmnt { color: #6272a4; font-style: italic; }
.shj-numbers { color: #6272a4; }
```

Display-mode hooks: `.shj-inline` (inside `code`), `.shj-block`, and `.shj-numbers` for the gutter. Terminal themes are the token-to-escape maps shown in [Terminal usage](#terminal-usage).

## Migrating from v1

| v1 | v2 |
| --- | --- |
| `highlightText(src, lang)` | `highlightHTML(src, lang)` |
| `printHighlight(src, lang)` from `/terminal` | `console.log(await highlightANSI(src, lang, theme))` |
| `setTheme('atom-dark')` | pass the theme: `highlightANSI(src, lang, theme)` |
| `loadLanguage(name, grammar)` | `setLoader(...)` or pass the grammar directly as `lang` |
| `@speed-highlight/core/terminal` entry | merged into `@speed-highlight/core` |
| `common.js` shared patterns | `{ expand: 'num' \| 'str' \| 'strDouble' }` built into the tokenizer |
| `{ hideLineNumbers: true }` | now the default, line numbers are opt-in with `{ showLineNumbers: true }` |
| `oneline` display mode | removed, a `div` is always a block |
| `highlightElement(elm, lang, mode, opt)` | the mode moved into the options: `highlightElement(elm, lang, { block })` |
| `shj-multiline` class | `shj-block` |

## Benchmark

<!-- AUTOGENERATED:BENCHMARK:START (run `npm run benchmark -- --write` to regenerate) -->
```rb
$ npm run benchmark
node v26.7.0, darwin arm64, Apple M4
corpus: js, css, json, md, sql, py, bash, tiled to 3 sizes (tiny (1 KB) / medium (16 KB) / huge (128 KB)), median of 9 trials per language, averaged across the corpus

                              tiny (1 KB)     medium (16 KB)      huge (128 KB)
speed-highlight         1,144,010 ops/min     74,720 ops/min      8,583 ops/min
prismjs                   655,152 ops/min     34,310 ops/min      2,575 ops/min
highlight.js              595,113 ops/min     48,666 ops/min      5,473 ops/min
sugar-high                238,406 ops/min     13,405 ops/min      1,376 ops/min
shiki (js engine)          89,925 ops/min      6,682 ops/min        841 ops/min

cold start (import + first highlight of test.js):
speed-highlight                    7.3 ms
prismjs                            8.6 ms
highlight.js                        19 ms
sugar-high                          18 ms
shiki (js engine)                  169 ms

speed-highlight per language (warm, median of 9 trials):
                              tiny (1 KB)     medium (16 KB)      huge (128 KB)
js                        666,642 ops/min     40,773 ops/min      4,704 ops/min
css                     1,006,895 ops/min     62,774 ops/min      7,284 ops/min
json                    1,964,840 ops/min    127,890 ops/min     15,057 ops/min
md                      1,080,739 ops/min     86,883 ops/min     10,453 ops/min
sql                     1,369,247 ops/min     88,513 ops/min     10,180 ops/min
py                        974,179 ops/min     56,165 ops/min      6,260 ops/min
bash                      945,526 ops/min     60,045 ops/min      6,141 ops/min
```
<!-- AUTOGENERATED:BENCHMARK:END -->

Identical inputs from [`examples/languages/`](examples/languages/), tiled up to each size bucket, HTML-string output for every library, one op = one highlighted file. Each figure is the median of 9 repeated trials, reported as ops/min (the huge bucket can drop below 1 op/sec for the slower libraries). Warm runs have grammars preloaded; cold start is import plus first highlight, measured once (not size-swept). Shiki does more work by design (see [Comparison](#comparison)).

---
_Source: https://npm.io/package/@speed-highlight/core · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
