Sugar High

Lightweight, zero-dependency syntax highlighter that turns code into HTML without a DOM, in browsers and JS runtimes alike.

Library
npm
v2.3.1
1,312stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
85/100Excellent
Development Activity100
Maintenance100
Community44
Maturity56
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
73/100Good
Architecture80
Code Quality82
Innovation68
Learning Curve60

Sugar High is a lightweight syntax highlighter built to convert source code into HTML without needing a browser DOM, so it runs equally well server-side, at build time, and in the browser. It ships zero runtime dependencies, supports around 30 built-in languages (from JavaScript and TypeScript to Rust, Go, SQL, and Dockerfile), and produces noticeably smaller minified and gzip bundles than PrismJS or highlight.js while covering the same core languages plus formats increasingly generated by AI coding agents.

Beyond the single-call highlight() API, the package exposes a composable core (sugar-high/core) that separates tokenizing/parsing from HTML rendering, letting consumers register only the languages they need, define custom keyword sets, or write bespoke comment/quote rules for languages Sugar High doesn’t ship. Companion packages add React components (@sugar-high/react, with <Code> and <Editor>) and a Remark plugin (@sugar-high/remark) for highlighting fenced code blocks in Markdown pipelines.

What You Get

  • A single highlight(code, { lang }) call that returns ready-to-style HTML with no DOM dependency, usable in Node, Deno, edge runtimes, or the browser
  • Around 30 built-in language grammars (JavaScript/JSX, TypeScript/TSX, Python, Rust, Go, Java, SQL, Dockerfile, HCL/Terraform, and more) selectable by canonical name
  • A composable sugar-high/core entry point for tree-shaking down to only the languages you use, plus per-language imports like sugar-high/lang/python
  • Token-level customization via cx class maps and a mutating mark() hook, plus zero-based markLine() for per-line highlighting
  • A lang() normalizer that maps file extensions and common aliases (py, bash, .yml) to the canonical language names highlight() expects

Common Use Cases

  • Blog and docs syntax highlighting - static site generators and MDX-based blogs call highlight() at build time to render code blocks as HTML without shipping a browser-only highlighter
  • AI coding agent output rendering - chat UIs and coding-agent interfaces highlight generated code across many languages and formats without adding a heavyweight dependency
  • In-browser code editors - the companion @sugar-high/react package layers a textarea-overlay <Editor> and <Code> block on top of the core highlighter for live-editable snippets
  • Custom DSL/config highlighting - sugar-high/core lets teams define keyword sets and comment rules to highlight a proprietary query language or config format without adopting a full grammar system

Under The Hood

Architecture Sugar High is a small, layered pipeline: tokenize() in core.js walks the source character-by-character into [type, value] token pairs (handling comments, quoted strings/template literals, whitespace, and word/sign runs), assemble() in shared.js groups those tokens into per-line structures, and render() turns parsed lines into HTML strings with createLine/createToken plus a small HTML-entity encoder. Language-specific behavior (keyword sets, comment rules, JSX/regex/template-string toggles) is expressed as plain ParseOptions objects in lib/lang/*.js and looked up through presets/configs.js’s configFor(name), so adding or overriding a language is a data change rather than a structural one; nonJavaScript() in configs.js strips JS-only scanner modes (jsx/regex/templateStrings) for every non-JS preset. The root highlight() in index.js is a thin wrapper composing parse() and render(), keeping the default API surface intentionally narrow while advanced composition lives behind sugar-high/core.

Tech Stack The package is authored directly in JavaScript with // @ts-check and JSDoc type annotations (no separate .ts source tree), type-checked via TypeScript 6.0.2 and distributed as ESM ("type": "module") with hand-maintained .d.ts declaration files alongside each .js module. It has zero runtime dependencies; the only devDependencies are typescript, vitest, and @types/node. The monorepo (pnpm workspaces, pnpm-workspace.yaml) houses this core package plus @sugar-high/react and @sugar-high/remark as sibling packages, with Changesets driving versioning and a GitHub Actions-based trusted-publishing (OIDC) release flow.

Code Quality Tests use Vitest across roughly 16 test files, split into core-behavior suites (tokenize.test.ts, core.test.ts, ast.test.ts) and one dedicated preset test per language family (test/preset/*.test.ts for C, Go, Java, Rust, Ruby, CSS, JSON, Python, diff, and more), several using inline Vitest snapshots to pin exact tokenization output. Options and return shapes are documented through JSDoc @typedefs (ParseOptions, DisplayOptions, MarkToken, ParsedLine) rather than a separate .ts source, giving IDE type-checking without a build step. CI runs a dedicated test.yml workflow plus a size-comment.yml workflow that reports bundle-size deltas on pull requests, reflecting the project’s stated priority of treating bundle size as an architectural constraint. The project’s own AGENTS.md codifies conventions (short canonical names, no duplicate exports, read-only registry data, Conventional Commits) that the maintainers hold contributions to.

API Design The default export surface is deliberately minimal: one highlight(code, options) function with a handful of orthogonal options (lang, cx, mark, markLine), which keeps the common path near zero-boilerplate - import { highlight } from 'sugar-high'; highlight(code) is a complete integration for JavaScript. Advanced needs (custom tokenizers, per-language tree-shaking, low-level class composition) are pushed into clearly named subpaths (sugar-high/core, sugar-high/lang, sugar-high/lang/*) instead of growing the root API, and the lang() alias normalizer removes the need for every integration to hand-roll its own extension/alias-to-language mapping. Documentation is split across a full API reference (docs/API.md), a migration guide for v1 upgraders (docs/MIGRATION.md), and a benchmark methodology doc (docs/BENCHMARK.md), which is unusually thorough for a package this size.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search