neo avatar
Neo Zero

highlight

Pool

Zero-dependency syntax highlighter - Fast, modern, tree-shakeable with React adapter and auto-scan support

$ lpm install @lpm.dev/neo.highlight

@lpm.dev/neo.highlight

Modern, zero-dependency syntax highlighter for the web.


Why This?

Every existing syntax highlighter requires tradeoffs -- bloated bundles, missing TypeScript support, runtime dependencies, or no tree-shaking. @lpm.dev/neo.highlight eliminates all of them.

Feature neo.highlight Prism.js highlight.js Shiki react-syntax-highlighter sugar-high
ESM native Yes No Partial Yes No Yes
TypeScript source Yes No No Yes No Yes
Zero dependencies Yes Yes Yes No (oniguruma) No (7+ deps) Yes
Bundle size (core) ~3.8 KB ~6 KB ~30 KB ~1 MB+ ~40 KB+ ~3 KB
Tree-shakeable Yes No No No No Partial
React adapter Built-in Plugin Plugin Plugin Core No
Auto-scan (DOM) Built-in Built-in Built-in No No No
MutationObserver Built-in No No No No No
SSR support Yes Manual Manual Yes Yes Yes
Languages 55 290+ 190+ 190+ 190+ ~10
Themes 10 8 90+ 30+ 80+ 1
CSS custom properties Yes No No No No Yes

Key Features

  • Zero dependencies -- nothing to install, nothing to break
  • ~3.8 KB core gzipped -- load only what you use
  • 55 languages with accurate grammar definitions
  • 10 themes including GitHub Dark, Dracula, Nord, Tokyo Night
  • React + Vanilla JS -- first-class adapters for both
  • Component mode -- <Highlight> for explicit code blocks
  • Auto-scan mode -- <AutoHighlight> / autoHighlight() finds and highlights <code> elements
  • MutationObserver -- watches for dynamically added code blocks in SPAs
  • CSS custom properties -- theme values exposed as --neo-hl-* variables
  • Tree-shakeable -- import only the languages and themes you need
  • SSR support -- getThemeStylesheet() generates CSS at build time
  • Full TypeScript -- strict mode, every type exported, zero any

Quick Start

Installation

lpm install @lpm.dev/neo.highlight

React

import { Highlight } from "@lpm.dev/neo.highlight/react";
import { javascript } from "@lpm.dev/neo.highlight/grammars/javascript";
import { githubDark } from "@lpm.dev/neo.highlight/themes/github-dark";

function App() {
  return (
    <Highlight language={javascript} theme={githubDark}>
      {`const greeting = "Hello, world!";
console.log(greeting);`}
    </Highlight>
  );
}

Vanilla JS

import { highlight } from "@lpm.dev/neo.highlight/vanilla";
import { javascript } from "@lpm.dev/neo.highlight/grammars/javascript";
import { githubDark } from "@lpm.dev/neo.highlight/themes/github-dark";

const html = highlight(`const greeting = "Hello, world!";`, javascript, {
  theme: githubDark,
  lineNumbers: true,
});

document.getElementById("code").innerHTML = html;

React API

Import from @lpm.dev/neo.highlight/react.

<Highlight>

Renders a single code block with syntax highlighting.

import { Highlight } from "@lpm.dev/neo.highlight/react";
import { typescript } from "@lpm.dev/neo.highlight/grammars/typescript";
import { dracula } from "@lpm.dev/neo.highlight/themes/dracula";

<Highlight
  language={typescript}
  theme={dracula}
  showLineNumbers
  highlightLines={[2, 3]}
  className="my-code-block"
>
  {`interface User {
  name: string;
  email: string;
}`}
</Highlight>;

Props:

Prop Type Default Description
children string required Source code to highlight
language Grammar required Grammar definition for the language
theme Theme | string from context Theme object or registered theme name
showLineNumbers boolean from context Show line numbers
highlightLines number[] -- Lines to highlight (1-indexed)
classPrefix string "neo-hl" CSS class prefix
className string -- Additional CSS class for the wrapper
style CSSProperties -- Inline styles for the wrapper
maxInputLength number 250000 Maximum tokenizer input length
maxMatchCount number 100000 Maximum regex matches
maxTokenCount number 100000 Maximum token nodes
maxRenderedLength number 10000000 Maximum HTML output length
maxLines number 10000 Maximum source lines
maxTokenDepth number 100 Maximum grammar and token depth

<AutoHighlight>

Scans its children for <code> elements and highlights them automatically. Uses MutationObserver to watch for dynamically added content.

Security: Sanitize untrusted HTML before you pass it to dangerouslySetInnerHTML. <AutoHighlight> does not sanitize its children.

import { AutoHighlight } from "@lpm.dev/neo.highlight/react";
import { javascript } from "@lpm.dev/neo.highlight/grammars/javascript";
import { python } from "@lpm.dev/neo.highlight/grammars/python";
import { githubDark } from "@lpm.dev/neo.highlight/themes/github-dark";

<AutoHighlight languages={[javascript, python]} theme={githubDark}>
  <article dangerouslySetInnerHTML={{ __html: sanitizedMarkdownHtml }} />
</AutoHighlight>;

Language is detected from class names (language-js, lang-python) or the data-language attribute on the <code> or <pre> element.

Set autoDetect to true when an element has no language hint. The detector uses token coverage and language-specific syntax.

Derived grammars need a unique marker before they can outrank their base grammar. For example, Astro needs frontmatter, and Vue needs framework directives.

This rule keeps plain HTML assigned to HTML. TypeScript, TSX, JSX, Svelte, Handlebars, SCSS, Less, and Bash use equivalent markers.

Props:

Prop Type Default Description
children ReactNode required Content containing <code> elements
languages Grammar[] from context Grammars available for detection
theme Theme | string from context Theme object or registered theme name
selector string "pre code" CSS selector for code elements
lineNumbers boolean from context Show line numbers
classPrefix string "neo-hl" CSS class prefix
className string -- Additional CSS class for the wrapper
style CSSProperties -- Inline styles for the wrapper
autoDetect boolean false Detect blocks without a language hint
maxInputLength number 250000 Maximum tokenizer input length
maxMatchCount number 100000 Maximum regex matches
maxTokenCount number 100000 Maximum token nodes
maxRenderedLength number 10000000 Maximum HTML output length
maxLines number 10000 Maximum source lines
maxTokenDepth number 100 Maximum grammar and token depth
onError (error, element) => void -- Receive errors for individual blocks

<HighlightProvider>

Provides default theme, languages, and options to all nested highlight components via React context. Avoids repeating props on every component.

import {
  HighlightProvider,
  Highlight,
  AutoHighlight,
} from "@lpm.dev/neo.highlight/react";
import { javascript } from "@lpm.dev/neo.highlight/grammars/javascript";
import { python } from "@lpm.dev/neo.highlight/grammars/python";
import { tokyoNight } from "@lpm.dev/neo.highlight/themes/tokyo-night";

function App() {
  return (
    <HighlightProvider
      theme={tokyoNight}
      languages={[javascript, python]}
      lineNumbers
    >
      {/* All children inherit theme, languages, and lineNumbers */}
      <Highlight language={javascript}>{`const x = 42;`}</Highlight>

      <AutoHighlight>
        <div dangerouslySetInnerHTML={{ __html: sanitizedBlogContent }} />
      </AutoHighlight>
    </HighlightProvider>
  );
}

Props:

Prop Type Default Description
children ReactNode required Child components
theme Theme | string -- Default theme for all children
languages Grammar[] [] Default grammars for auto-highlight
classPrefix string "neo-hl" Default CSS class prefix
lineNumbers boolean false Default line numbers setting

useHighlight

Hook for full control over tokenization and rendering. Returns both the raw token array and the rendered HTML string, both memoized.

import { useHighlight } from "@lpm.dev/neo.highlight/react";
import { rust } from "@lpm.dev/neo.highlight/grammars/rust";
import { nord } from "@lpm.dev/neo.highlight/themes/nord";

function CodeBlock({ code }: { code: string }) {
  const { tokens, html } = useHighlight(code, rust, {
    theme: nord,
    lineNumbers: true,
    highlightLines: [1],
    wrapCode: true,
  });

  // Use `html` directly
  return <div dangerouslySetInnerHTML={{ __html: html }} />;

  // Or iterate over `tokens` for custom rendering
}

Parameters:

Parameter Type Description
code string Source code to highlight
language Grammar Grammar definition
options UseHighlightOptions Theme, line numbers, highlight lines, class prefix, wrapCode

Returns: { tokens: Token[], html: string }

useHighlightContext

Access the current HighlightProvider context values directly.

import { useHighlightContext } from "@lpm.dev/neo.highlight/react";

function DebugInfo() {
  const { theme, languages, classPrefix, lineNumbers } = useHighlightContext();
  // ...
}

Vanilla API

Import from @lpm.dev/neo.highlight/vanilla.

highlight(code, language, options?)

Highlight source code and return an HTML string.

import { highlight } from "@lpm.dev/neo.highlight/vanilla";
import { python } from "@lpm.dev/neo.highlight/grammars/python";
import { oneDark } from "@lpm.dev/neo.highlight/themes/one-dark";

const html = highlight(
  `def greet(name):
    return f"Hello, {name}!"`,
  python,
  {
    theme: oneDark,
    lineNumbers: true,
    highlightLines: [2],
    wrapCode: true,
  },
);

Options:

Option Type Default Description
theme Theme | string -- Theme object or registered name
lineNumbers boolean false Show line numbers
highlightLines number[] -- Lines to highlight (1-indexed)
classPrefix string "neo-hl" CSS class prefix
wrapCode boolean true Wrap output in <pre><code>
maxInputLength number 250000 Maximum tokenizer input length
maxMatchCount number 100000 Maximum regex matches
maxTokenCount number 100000 Maximum token nodes
maxRenderedLength number 10000000 Maximum HTML output length
maxLines number 10000 Maximum source lines
maxTokenDepth number 100 Maximum grammar and token depth

autoHighlight(options)

Scan the page for code blocks and optionally observe for dynamically added ones. Returns a cleanup function.

import { autoHighlight } from "@lpm.dev/neo.highlight/vanilla";
import { javascript } from "@lpm.dev/neo.highlight/grammars/javascript";
import { typescript } from "@lpm.dev/neo.highlight/grammars/typescript";
import { css } from "@lpm.dev/neo.highlight/grammars/css";
import { githubDark } from "@lpm.dev/neo.highlight/themes/github-dark";

// Highlight all existing code blocks and watch for new ones
const cleanup = autoHighlight({
  languages: [javascript, typescript, css],
  theme: githubDark,
  observe: true, // Use MutationObserver for SPAs
  selector: "pre code", // CSS selector to match
  lineNumbers: false,
});

// Later, to stop observing:
cleanup();

Language detection reads from the <code> or <pre> element:

  • class="language-javascript" or class="lang-js"
  • data-language="javascript"

scan(options)

One-shot scan. Finds all matching elements and highlights them. Returns the number of elements highlighted.

import { scan } from "@lpm.dev/neo.highlight/vanilla";
import { javascript } from "@lpm.dev/neo.highlight/grammars/javascript";

const count = scan({
  languages: [javascript],
  selector: "pre code",
  container: document.getElementById("article"),
  force: true, // Refresh blocks that are already highlighted
  onError: (error, element) => console.error(element, error),
});

console.log(`Highlighted ${count} code blocks`);

A one-shot scan applies the theme foreground and background directly to each code element. It does not add a style element.

An error in one block does not stop the scan. Use onError to receive that error.

observe(options)

Continuous scan. Highlights existing elements, then uses MutationObserver to watch for new ones. Returns a cleanup function.

import { observe } from "@lpm.dev/neo.highlight/vanilla";
import { javascript } from "@lpm.dev/neo.highlight/grammars/javascript";
import { githubDark } from "@lpm.dev/neo.highlight/themes/github-dark";

const disconnect = observe({
  languages: [javascript],
  theme: githubDark,
  container: document.body,
});

// Stop observing when done:
disconnect();

Web Worker

The worker entry runs tokenization outside the main thread. It contains all built-in grammars.

Create a worker module named highlight-worker.ts:

import "@lpm.dev/neo.highlight/worker";

Create the worker from the application module:

const worker = new Worker(new URL("./highlight-worker.ts", import.meta.url), {
  type: "module",
});

worker.postMessage({
  id: 1,
  code: "const x = 42;",
  language: "javascript",
  maxInputLength: 100_000,
});

worker.addEventListener("message", (event) => {
  if (event.data.ok) {
    console.log(event.data.tokens);
  } else {
    console.error(event.data.error);
  }
});

The worker accepts built-in language names and aliases. Each response contains the request id.

Resource limits

All entry points enforce resource limits. The limits apply to UTF-16 units, regex matches, token nodes, HTML output, lines, and nesting depth.

Option Default Scope
maxInputLength 250000 Tokenizer input
maxMatchCount 100000 Regex matches
maxTokenCount 100000 Created or rendered token nodes
maxRenderedLength 10000000 Generated HTML
maxLines 10000 Rendered source lines
maxTokenDepth 100 Grammar and token-tree nesting

You can set each limit to Infinity for trusted source code. Finite limits are safer for user-controlled source code.

CAUTION: Treat custom grammars as trusted executable regex configuration. One unsafe regex can block the JavaScript thread before a counter can stop it.

Do not accept custom grammar objects from untrusted users. For custom grammars, use a worker and terminate it after an application deadline.

The package tests every built-in grammar with adversarial input. Each regex test runs in an isolated subprocess with a hard timeout.


Core Utilities

Import from @lpm.dev/neo.highlight.

resolveGrammar(language, grammars)

Resolve a language string to a Grammar object by checking grammar names and aliases. Useful when you have a language identifier from user input (e.g. "js", "py", "tsx") and need to find the matching grammar.

import { resolveGrammar } from "@lpm.dev/neo.highlight";
import { javascript, python, typescript } from "@lpm.dev/neo.highlight/grammars";

const grammars = [javascript, python, typescript];

resolveGrammar("js", grammars);         // → javascript grammar
resolveGrammar("python", grammars);     // → python grammar
resolveGrammar("typescript", grammars); // → typescript grammar
resolveGrammar("unknown", grammars);    // → undefined

Parameters:

Parameter Type Description
language string Language name or alias
grammars Grammar[] Array of grammars to search in

The lookup ignores case and surrounding whitespace in names and aliases.

Returns: Grammar | null

validateThemeContrast(theme)

Validate a theme's token colors against WCAG AA contrast requirements (4.5:1 minimum ratio). Returns a detailed per-token report.

import { validateThemeContrast } from "@lpm.dev/neo.highlight";
import { nord } from "@lpm.dev/neo.highlight/themes/nord";

const report = validateThemeContrast(nord);
// report.passed — true if all results pass
// report.theme — theme name
// report.results — array of
// { token, color, background, ratio, required, pass }

Returns: ThemeContrastReport

contrastRatio(color1, color2)

Calculate the WCAG 2.0 contrast ratio between two hex colors. Returns a value between 1 and 21.

import { contrastRatio } from "@lpm.dev/neo.highlight";

contrastRatio("#ffffff", "#000000"); // → 21
contrastRatio("#767676", "#ffffff"); // → ~4.54

meetsWCAG_AA(foreground, background, isLargeText?)

Check whether a foreground/background color pair meets WCAG AA. Normal text requires 4.5:1; large text (18px+ bold or 24px+) requires 3:1.

import { meetsWCAG_AA } from "@lpm.dev/neo.highlight";

meetsWCAG_AA("#767676", "#ffffff");        // → true  (4.54:1 >= 4.5)
meetsWCAG_AA("#808080", "#ffffff");        // → false (3.95:1 < 4.5)
meetsWCAG_AA("#808080", "#ffffff", true);  // → true  (3.95:1 >= 3.0 for large text)

hexToRGB(hex)

Parse a hex color string ("#rgb" or "#rrggbb") to an [r, g, b] tuple.

import { hexToRGB } from "@lpm.dev/neo.highlight";

hexToRGB("#ff9e64"); // → [255, 158, 100]
hexToRGB("#fff");    // → [255, 255, 255]

relativeLuminance(r, g, b)

Calculate the WCAG 2.0 relative luminance of an RGB color. Returns a value between 0 (black) and 1 (white).

import { relativeLuminance } from "@lpm.dev/neo.highlight";

relativeLuminance(255, 255, 255); // → 1
relativeLuminance(0, 0, 0);       // → 0

getDualThemeStylesheet(lightTheme, darkTheme, options?)

Generate a CSS stylesheet containing both light and dark theme variables. By default uses @media (prefers-color-scheme: dark) to switch; pass darkSelector for class-based toggling.

import { getDualThemeStylesheet } from "@lpm.dev/neo.highlight";
import { solarizedLight } from "@lpm.dev/neo.highlight/themes/solarized-light";
import { solarizedDark } from "@lpm.dev/neo.highlight/themes/solarized-dark";

// Media query (default)
const css = getDualThemeStylesheet(solarizedLight, solarizedDark);

// Class-based
const css2 = getDualThemeStylesheet(solarizedLight, solarizedDark, {
  darkSelector: "[data-theme='dark']",
});

Options:

Option Type Default Description
darkSelector string @media (prefers-color-scheme: dark) rule CSS selector to scope the dark overrides

Languages

55 languages with tree-shakeable imports. Import only what you need.

// Import a single language
import { javascript } from "@lpm.dev/neo.highlight/grammars/javascript";

// Or import several
import {
  javascript,
  typescript,
  python,
} from "@lpm.dev/neo.highlight/grammars";
Language Import Aliases
JavaScript javascript js, mjs, cjs
TypeScript typescript ts, mts, cts
Python python py
JSX jsx react
TSX tsx --
HTML html htm, xml, svg, mathml
CSS css --
SCSS scss sass
JSON json jsonc, json5
YAML yaml yml
Markdown markdown md, mdx
GraphQL graphql gql
Ruby ruby rb
Go go golang
Rust rust rs
Java java --
Kotlin kotlin kt, kts
Swift swift --
PHP php --
C c h
C++ cpp c++, cxx, cc, hpp, hxx, hh
C# csharp cs, c#, dotnet
Bash bash zsh
Shell shell sh, posix-shell
Dockerfile docker dockerfile
SQL sql mysql, pgsql, postgres, postgresql, sqlite, plsql
TOML toml --
INI ini conf, cfg, env, properties
Diff diff patch
Regex regex regexp
Lua lua --
Dart dart --
Elixir elixir ex, exs
Scala scala sc
R r rlang
Svelte svelte --
Vue vue vue-html
Astro astro --
Zig zig --
WASM wasm wat, wast
Haskell haskell hs
Erlang erlang erl
Clojure clojure clj, cljs, cljc, edn
OCaml ocaml ml
Perl perl pl
Objective-C objectivec objc, obj-c
PowerShell powershell ps1, posh
Terraform terraform hcl, tf
Prisma prisma --
Nix nix nixos
LaTeX latex tex
Less less --
Handlebars handlebars hbs, mustache
Solidity solidity sol
CSV csv tsv

Themes

10 built-in themes with tree-shakeable imports.

// Import a single theme
import { githubDark } from "@lpm.dev/neo.highlight/themes/github-dark";

// Or import several
import { githubDark, dracula, nord } from "@lpm.dev/neo.highlight/themes";
Theme Import Description
GitHub Dark githubDark GitHub's dark mode color scheme
GitHub Light githubLight GitHub's light mode color scheme
One Dark oneDark Atom One Dark theme
Dracula dracula Dracula color scheme
Nord nord Arctic, north-bluish color palette
Monokai monokai Classic Monokai color scheme
Solarized Light solarizedLight Ethan Schoonover's Solarized (light)
Solarized Dark solarizedDark Ethan Schoonover's Solarized (dark)
Night Owl nightOwl Sarah Drasner's Night Owl theme
Tokyo Night tokyoNight Inspired by Tokyo city lights at night

All built-in themes pass WCAG AA contrast requirements (4.5:1 minimum ratio against their background).


Theme Accessibility

Validate any theme (built-in or custom) against WCAG AA contrast requirements using validateThemeContrast():

import { validateThemeContrast } from "@lpm.dev/neo.highlight";
import { dracula } from "@lpm.dev/neo.highlight/themes/dracula";

const report = validateThemeContrast(dracula);

console.log(report.passed); // true — all colors meet the ratio
console.log(report.theme); // "dracula"

for (const result of report.results) {
  console.log(
    `${result.token}: ${result.ratio.toFixed(1)}:1 — ${result.pass ? "PASS" : "FAIL"}`,
  );
}

Each result includes a token name, color, background, ratio, required ratio, and pass status. The foreground result checks the theme's base text color.


Dual Theme (Light/Dark)

Generate a stylesheet that switches between a light and a dark theme automatically using getDualThemeStylesheet():

Using prefers-color-scheme (default)

import { getDualThemeStylesheet } from "@lpm.dev/neo.highlight";
import { githubLight } from "@lpm.dev/neo.highlight/themes/github-light";
import { githubDark } from "@lpm.dev/neo.highlight/themes/github-dark";

const css = getDualThemeStylesheet(githubLight, githubDark);
// Produces CSS with:
//   Root styles use githubLight values
//   @media (prefers-color-scheme: dark) { ... } overrides with githubDark values

Using a class selector

const css = getDualThemeStylesheet(githubLight, githubDark, {
  darkSelector: ".dark",
});
// Produces CSS with:
//   Root styles use githubLight values
//   .dark { ... } overrides with githubDark values

Inject the returned CSS into a <style> tag. Theme switching works without any JavaScript -- it follows the user's OS preference or your class toggle.


Custom Themes

Create a custom theme by defining a Theme object:

import type { Theme } from "@lpm.dev/neo.highlight";

const myTheme: Theme = {
  name: "my-theme",
  background: "#1a1b26",
  foreground: "#c0caf5",
  selection: "#33467c",
  lineNumber: "#3b4261",
  lineNumberActive: "#c0caf5",
  lineHighlight: "#292e42",
  tokenColors: {
    comment: "#565f89",
    keyword: "#9d7cd8",
    string: "#9ece6a",
    number: "#ff9e64",
    boolean: "#ff9e64",
    function: "#7aa2f7",
    operator: "#89ddff",
    punctuation: "#c0caf5",
    variable: "#c0caf5",
    "class-name": "#f7768e",
    constant: "#ff9e64",
    property: "#73daca",
    tag: "#f7768e",
    "attr-name": "#7aa2f7",
    "attr-value": "#9ece6a",
    selector: "#9ece6a",
    regex: "#b4f9f8",
    builtin: "#7aa2f7",
    important: "#f7768e",
    inserted: "#9ece6a",
    deleted: "#f7768e",
    changed: "#ff9e64",
    namespace: "#9d7cd8",
    parameter: "#e0af68",
    interpolation: "#73daca",
    "template-string": "#9ece6a",
    decorator: "#9d7cd8",
  },
};

Theme colors are applied as inline CSS custom properties (--neo-hl-*) and can be overridden in your own stylesheets:

.neo-hl {
  --neo-hl-bg: #1e1e2e;
  --neo-hl-fg: #cdd6f4;
  --neo-hl-keyword: #cba6f7;
  --neo-hl-string: #a6e3a1;
}

Use with neo.markdown

neo.highlight integrates with @lpm.dev/neo.markdown via its highlight plugin. Pass tokenize, renderToHTML, and getThemeStylesheet directly:

import { createParser } from "@lpm.dev/neo.markdown";
import { highlightPlugin } from "@lpm.dev/neo.markdown/plugins/highlight";
import { tokenize, renderToHTML, getThemeStylesheet } from "@lpm.dev/neo.highlight";
import { javascript, typescript, python } from "@lpm.dev/neo.highlight/grammars";
import { githubDark } from "@lpm.dev/neo.highlight/themes/github-dark";

const parser = createParser({
  plugins: [
    highlightPlugin({
      grammars: [javascript, typescript, python],
      tokenize,
      renderToHTML,
      getThemeStylesheet,
      theme: githubDark,
    }),
  ],
});

const html = parser.parse(markdownString);

Code blocks in the markdown output are automatically syntax-highlighted with proper theme colors.


SSR Support

Both the React and vanilla APIs work in server-side rendering environments out of the box. The highlight() function and <Highlight> component produce static HTML strings with inline styles -- no client-side JavaScript is required to display the highlighted code.

For server rendering, use getThemeStylesheet() to generate a CSS stylesheet string that can be injected into a <style> tag:

import { getThemeStylesheet } from "@lpm.dev/neo.highlight";
import { githubDark } from "@lpm.dev/neo.highlight/themes/github-dark";

const css = getThemeStylesheet(githubDark);
// Inject into <style> tag in your HTML template

In a Next.js or similar framework:

import { getThemeStylesheet } from "@lpm.dev/neo.highlight";
import { githubDark } from "@lpm.dev/neo.highlight/themes/github-dark";

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        <style
          dangerouslySetInnerHTML={{ __html: getThemeStylesheet(githubDark) }}
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

Bundle Size

Every grammar and theme is a separate module. Import only what you need.

Import Gzipped
Core (tokenizer + renderer) ~3.8 KB
Core + 1 language ~4.2 KB
React adapter ~1.2 KB
Vanilla adapter ~0.8 KB
Single theme ~0.3 KB
Single grammar (avg) ~0.4 KB
All 55 grammars ~22 KB
All 10 themes ~3 KB

The package marks only the worker entry as side-effectful. Bundlers can tree-shake all other unused exports.


TypeScript

Written in strict TypeScript. All types are exported from the main entry point:

import type {
  Token,
  TokenNode,
  TokenPattern,
  TokenDefinition,
  Grammar,
  GrammarTokens,
  Theme,
  ThemeTokenColors,
  RenderOptions,
  ScanOptions,
  GrammarRegistry,
} from "@lpm.dev/neo.highlight";

React-specific types:

import type {
  HighlightProps,
  AutoHighlightProps,
  HighlightProviderProps,
  UseHighlightOptions,
  UseHighlightResult,
} from "@lpm.dev/neo.highlight/react";

Vanilla-specific types:

import type {
  HighlightOptions,
  ScanOptions,
} from "@lpm.dev/neo.highlight/vanilla";
syntaxhighlightcodeprismhighlightjsreacttypescriptesmtree-shakeablezero-dependencymodernneo
Unlimited AccessInstall as many Pool packages as you need.
Fund Real WorkEvery install you run sends revenue directly to the developer who built it.

Taxes calculated at checkout based on your location.

Weekly Installs
109
Version
1.3.0
Published
LicenseMIT
Size1.29 MiB
Files717
Node version>= 18
TypeScriptYes