sql-highlight
sql-highlight is a dependency-free SQL tokenizer and syntax colorizer for logs and web pages. Its `highlight` function wraps recognized tokens in ANSI color codes for terminals or escaped `<span>` elements for HTML, while `getSegments` exposes the token stream for custom rendering. It uses regular expressions and a keyword list rather than a dialect-aware SQL parser, so it is appropriate for display, not validation, formatting, query rewriting, or security analysis.
A very small, practical choice for coloring SQL in Node logs or simple HTML. Do not mistake the flat regex token stream for a formatter, parser, or dialect-aware analysis tool.
Use it if
- You want readable SQL in Node.js logs with no runtime dependencies
- You need small HTML output with stable token classes that you can style yourself
- You want raw keyword, string, number, identifier, comment, and punctuation segments for a custom renderer
- You need one synchronous API for both terminal colors and browser-oriented HTML
- You need SQL formatting or indentation; the library preserves input spacing and only adds color markup
- You need dialect-aware parsing or validation; tokenization is regex-based and has no PostgreSQL, MySQL, SQLite, or T-SQL mode
- You need ESM-first packaging or a documented CDN build; version 6.1.0 exposes a CommonJS main entry and requires Node 14 or newer
- You already use highlight.js, Prism, or Shiki for many languages; adding a SQL-only highlighter creates a second theme and rendering path
- You need semantic identifiers or an AST; getSegments returns flat name/content pairs and cannot tell a table name from a column name
Setup reality
Install with `npm install sql-highlight`. There are no runtime dependencies, peers, native modules, credentials, or configuration files, and Bundlephobia measures the minified package at 1.5 KB gzipped. Version 6.1.0 declares Node 14 or newer and publishes a CommonJS entry with bundled TypeScript declarations, so the documented form is `const { highlight } = require('sql-highlight')`; bundlers can consume it, but there is no exports map or native ESM module entry. Terminal output is the default and contains ANSI escape codes, which means writing it to JSON logs, files, or non-color-aware collectors can leave control sequences in stored text. HTML output must be explicitly enabled with `{ html: true }`. It escapes token content with a built-in escaper before adding spans, but it supplies no stylesheet, so copy or adapt the sample CSS and keep the configured class prefix in sync. The tokenizer is lexical, not a SQL grammar: double-quoted text is treated as a string, backticks as identifiers, any word followed by optional whitespace and `(` as a function, and comments between a function name and its opening parenthesis are a documented unsupported case. Custom `colors` replaces the whole nested colors object because options are merged shallowly; spread `DEFAULT_OPTIONS.colors` when changing one color or the unspecified token types will lose coloring. The same caution applies to a custom `htmlEscaper`: returning unsafe text makes later `innerHTML` insertion unsafe.
Patterns
Color SQL for a terminalhighlight-terminal-sql
const { highlight } = require('sql-highlight')
const sql = 'SELECT id, email FROM users WHERE active = 1'
console.log(highlight(sql))ANSI output is the default; avoid storing it in structured logs or files unless consumers expect control codes.
Render SQL as escaped HTML spanshighlight-html
const { highlight } = require('sql-highlight')
const html = highlight(sql, { html: true })
codeElement.innerHTML = htmlToken content is escaped by default, but the package does not include CSS in its published files.
Style generated token classesstyle-html-output
.sql-hl-keyword { color: #c678dd; }
.sql-hl-function { color: #61afef; }
.sql-hl-string, .sql-hl-number { color: #98c379; }
.sql-hl-comment { color: #7f848e; font-style: italic; }
.sql-hl-special, .sql-hl-bracket { color: #abb2bf; }HTML mode emits only spans; define classes for every token type your theme needs.
Use namespaced HTML classeschange-class-prefix
const html = highlight(sql, {
html: true,
classPrefix: 'query-token-',
})The emitted classes become query-token-keyword, query-token-string, and so on, so update CSS at the same time.
Provide a DOM-based HTML escapercustom-html-escaper
const html = highlight(sql, {
html: true,
htmlEscaper(value) {
const node = document.createElement('div')
node.textContent = value
return node.innerHTML
},
})A custom escaper runs for every token. It must escape, not merely return the input, when output is assigned through innerHTML.
Change one ANSI color safelycustomize-one-color
const { highlight, DEFAULT_OPTIONS } = require('sql-highlight')
const output = highlight(sql, {
colors: {
...DEFAULT_OPTIONS.colors,
keyword: '\x1b[36m',
},
})Options use a shallow merge. Passing only `{ keyword: ... }` without spreading defaults removes the other configured colors.
Produce unchanged-looking terminal textdisable-terminal-colors
const { highlight } = require('sql-highlight')
const output = highlight(sql, {
colors: {
keyword: '', function: '', number: '', string: '', identifier: '',
special: '', bracket: '', comment: '', clear: '',
},
})For plain output, keeping the original SQL is cheaper; this pattern is useful only when one rendering pipeline requires highlight().
Get flat SQL segmentstokenize-sql
const { getSegments } = require('sql-highlight')
for (const segment of getSegments(sql)) {
console.log(segment.name, JSON.stringify(segment.content))
}Segments are lexical name/content pairs, not an AST and not proof that the SQL is valid.
Collect recognized keywordscollect-sql-keywords
const { getSegments } = require('sql-highlight')
const keywords = getSegments(sql)
.filter(({ name }) => name === 'keyword')
.map(({ content }) => content.toUpperCase())Recognition uses the library's built-in keyword list and is case-insensitive; there is no per-dialect list option.
Render segments as React elementsrender-react-segments
import { getSegments } from 'sql-highlight'
function SqlCode({ sql }) {
return <code>{getSegments(sql).map((part, index) => (
<span className={`sql-hl-${part.name}`} key={index}>{part.content}</span>
))}</code>
}React escapes part.content automatically; do not convert the result to an HTML string first.
Highlight a multiline queryhighlight-multiline-query
const output = highlight(`
SELECT u.id, COUNT(o.id)
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id
`)
console.log(output)Whitespace is retained exactly. This highlighter does not indent or reformat the query.
Color SQL commentshighlight-comments
const output = highlight(`
-- active customers only
SELECT * FROM customers WHERE active = 1;
/* review this predicate */
`)
console.log(output)The tokenizer recognizes double-dash, hash, and block comments, but it does not apply dialect-specific comment rules.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| sql-formatter | npm | Choose it when consistent indentation and dialect-aware formatting matter more than terminal colors |
| highlight.js | npm | Choose it when the same automatic highlighter must cover SQL plus many other languages |
| shiki | npm | Choose it for editor-grade tokenization and rich themes in documentation or build-time rendering |
| prismjs | npm | Choose it for client-side code blocks in an existing Prism theme and plugin setup |