sugar-high
v2.2.2
Published
Lightweight, zero-dependency syntax highlighting for popular programming languages
Readme
Sugar High
Lightweight, zero-dependency syntax highlighting for JavaScript, popular programming languages, and formats commonly generated by coding agents. It runs in browsers and JavaScript runtimes and returns HTML without requiring a DOM.
Install
npm install sugar-highHighlight code
import { highlight } from 'sugar-high'
const html = highlight('const ready = true')JavaScript, including JSX, is the default. Pass a canonical name for another built-in language:
highlight('print("hi")', { lang: 'python' })
highlight('{"ready": true}', { lang: 'json' })
highlight('+ added', { lang: 'diff' })The lang option is typed and accepts canonical names only.
Advanced: normalize extensions and aliases
You do not need lang() when the language is already known. Use it only when input comes from a
filename extension, Markdown fence, or another integration. It converts aliases to the canonical
name expected by highlight:
import { lang } from 'sugar-high/lang'
lang('py') // 'python'
lang('bash') // 'shell'
lang('jsonc') // 'json'
lang('.yml') // 'yaml'If you already have a canonical name, pass it directly—lang() is not required.
See the API reference for the complete mapping and normalization behavior.
Built-in languages
javascript, typescript, css, python, c, go, java, rust, json, diff, shell,
cpp, csharp, sql, html, yaml, markdown, plaintext, ruby, kotlin, swift, php,
toml, powershell, dockerfile, graphql, and hcl.
Related dialects share one implementation: JavaScript includes JSX, TypeScript includes TSX, JSON includes JSONC comments, Shell includes sh/Bash/Zsh, and HCL includes Terraform.
Composable core
Use sugar-high/core to separate configurable syntax parsing from HTML rendering. It does not
include the built-in language registry:
import { parse, render } from 'sugar-high/core'
const parsed = parse('select * from users', {
keywords: new Set(['select', 'from', 'where']),
})
const html = render(parsed, {
cx: { keyword: 'font-bold' },
})If bundle size matters and you only need a few built-in languages, import their configurations
directly instead of loading the complete registry from sugar-high or sugar-high/lang:
import { parse, render } from 'sugar-high/core'
import * as css from 'sugar-high/lang/css'
import * as python from 'sugar-high/lang/python'
const languages = { css, python }
const highlight = (code, language) =>
render(parse(code, languages[language]))Use the default sugar-high export when you want built-in languages and one-step highlight().
Customize tokens
Use cx for a class map. It works well with utility CSS, CSS Modules, and global styles while
preserving Sugar High's semantic token classes.
highlight(source, {
lang: 'typescript',
cx: {
keyword: 'font-bold',
comment: 'italic opacity-60',
},
})Use mark(token) for conditional classes, inline styles, or custom attributes. It mutates the
token and returns nothing:
highlight(source, {
mark(token) {
if (token.type === 'comment' && token.value.includes('TODO')) {
token.className += ' text-orange-500'
token.properties['data-todo'] = true
}
},
})cx runs before mark, so mark receives the composed class name.
Highlight lines
Use markLine to customize generated lines. Its index is zero-based:
highlight(source, {
markLine(line) {
if (line.index === 1) {
line.className += ' sh__line--highlighted'
}
},
})Style the class with CSS. The React package also provides the one-based
highlightLines={[1, [4, 7]]} prop, while the Remark plugin reads ranges from fence metadata such
as {2,5-7}.
Styling
Each line uses .sh__line. Token colors use CSS custom properties, so a theme can be embedded in
your own stylesheet or scoped to any ancestor:
.code {
--sh-class: #2d5e9d;
--sh-identifier: #354150;
--sh-sign: #8996a3;
--sh-property: #0550ae;
--sh-entity: #249a97;
--sh-jsxliterals: #6266d1;
--sh-string: #00a99a;
--sh-keyword: #f47067;
--sh-comment: #a19595;
}Lines can be styled or numbered with ordinary CSS:
pre code {
counter-reset: line;
}
.sh__line {
display: block;
}
.sh__line::before {
counter-increment: line;
content: counter(line);
margin-right: 1.5rem;
color: #a4a4a4;
}
.sh__line:nth-child(5),
.sh__line--highlighted {
background: #fff8c5;
}React
@sugar-high/react provides a highlighted <Code /> block
and textarea-overlay <Editor /> as separate composable exports.
import { Code, Editor } from '@sugar-high/react'
<Editor lang="typescript" value={source} onChange={setSource} />
<Code lang="typescript" lineNumbers>{source}</Code>Remark
@sugar-high/remark highlights fenced code blocks while
processing Markdown. Fence aliases are normalized through the same lang() mapping.
API
See docs/API.md for package exports, the full language mapping, highlighting
options, and lower-level functions. Upgrading from v1? Read the
v2 migration guide.
License
MIT
