new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Bun · Runtime · all subjects

bun apis/parsing & formatting

112 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

Parsing and formatting APIs: Bun.semver, TOML, XML, markdown, color, Image

Bun provides parsing and formatting utilities: Bun.semver for semantic version parsing, Bun.TOML.parse() for TOML parsing, Bun.XML for XML processing, Bun.markdown for markdown parsing, Bun.color for color parsing/formatting, and Bun.Image for image processing.

Bun.color 'ansi-16' conversion algorithm

The 'ansi-16' format converts input to 24-bit RGB color space, then to 'ansi-256', then approximates to the nearest of the 16 ANSI colors supported by most terminals.

Bun.color 'ansi-256' conversion algorithm

The 'ansi-256' format approximates the input color to the nearest of the 256 ANSI colors using the algorithm that tmux uses.

Bun.color API signature

Bun.color(input, outputFormat?) parses, normalizes, and converts colors from user input to any of multiple output formats. The outputFormat parameter is optional.

Bun.color '{rgba}' object format

The '{rgba}' format returns an object with properties: r (0-255), g (0-255), b (0-255), a (0-1 decimal). The alpha channel is a decimal number between 0 and 1.

Bun.color '{rgb}' object format

The '{rgb}' format returns an object with properties: r (0-255), g (0-255), b (0-255). It does not include the alpha channel.

Bun.color '[rgb]' array format

The '[rgb]' array format returns [r, g, b] where all values are 0-255 integers. It does not include the alpha channel.

Bun.color 'css' format compactness

The 'css' format outputs valid CSS for stylesheets, inline styles, CSS variables, or CSS-in-JS, returning the most compact string representation of the color.

Bun.color 'number' format for databases

The 'number' format outputs the color as a 24-bit number, which is a compact representation suitable for databases and configuration.

Bun.color use cases

Bun.color is used to: validate and normalize colors for database persistence (with 'number' being most database-friendly), convert colors to different formats, color terminal output beyond the basic 16 colors (using 'ansi' for auto-detection or specific formats like 'ansi-16', 'ansi-256', or 'ansi-16m'), format colors for CSS injection into HTML, and extract r, g, b, and a color components as JavaScript objects or numbers from CSS color strings.

Bun.color as built-in alternative

Bun.color is a built-in alternative to npm packages 'color' and 'tinycolor2', with full support for parsing CSS color strings and zero dependencies.

Bun.color CSS parsing

Bun.color uses Bun's CSS parser to parse, normalize, and convert colors.

Bun.color example CSS output

Bun.color('red', 'css') returns 'red'. All these inputs produce 'red': 0xff0000, '#f00', '#ff0000', 'rgb(255, 0, 0)', 'rgba(255, 0, 0, 1)', 'hsl(0, 100%, 50%)', 'hsla(0, 100%, 50%, 1)', {r: 255, g: 0, b: 0}, {r: 255, g: 0, b: 0, a: 1}, [255, 0, 0], [255, 0, 0, 255].

Bun.color example ANSI output

Bun.color('red', 'ansi') returns '\u001b[38;2;255;0;0m'. All these inputs produce the same output: 0xff0000, '#f00', '#ff0000', 'rgb(255, 0, 0)', 'rgba(255, 0, 0, 1)', 'hsl(0, 100%, 50%)', 'hsla(0, 100%, 50%, 1)', {r: 255, g: 0, b: 0}, {r: 255, g: 0, b: 0, a: 1}, [255, 0, 0], [255, 0, 0, 255].

Bun.color input formats

Bun.color accepts: standard CSS color names like 'red', numbers like 0xff0000, hex strings like '#f00', RGB strings like 'rgb(255, 0, 0)', RGBA strings like 'rgba(255, 0, 0, 1)', HSL strings like 'hsl(0, 100%, 50%)', HSLA strings like 'hsla(0, 100%, 50%, 1)', RGB objects like {r: 255, g: 0, b: 0}, RGBA objects like {r: 255, g: 0, b: 0, a: 1}, RGB arrays like [255, 0, 0], RGBA arrays like [255, 0, 0, 255], LAB strings like 'lab(50% 50 50)', and anything else that CSS can parse as a single color value.

Bun.color example ANSI-256 output

Bun.color('red', 'ansi-256') returns '\u001b[38;5;196m'. All these inputs produce the same output: 0xff0000, '#f00', '#ff0000'.

Bun.color example ANSI-16 output

Bun.color('red', 'ansi-16') returns '\u001b[91m'. All these inputs produce the same output: 0xff0000, '#f00', '#ff0000'.

Bun.color example number output

Bun.color('red', 'number') returns 16711680. These inputs produce the same output: 0xff0000, {r: 255, g: 0, b: 0}, [255, 0, 0], 'rgb(255, 0, 0)', 'rgba(255, 0, 0, 1)', 'hsl(0, 100%, 50%)', 'hsla(0, 100%, 50%, 1)'.

Bun.color output formats

Bun.color supports these output formats: 'css' (returns CSS color name like 'red'), 'ansi' (ANSI escape codes like '\x1b[38;2;255;0;0m'), 'ansi-16' (basic 16 color ANSI like '\x1b[91m'), 'ansi-256' (256 color approximation like '\x1b[38;5;196m'), 'ansi-16m' (24-bit ANSI like '\x1b[38;2;255;0;0m'), 'number' (24-bit integer like 0x1a2b3c), 'rgb' (CSS string like 'rgb(255, 99, 71)'), 'rgba' (CSS string like 'rgba(255, 99, 71, 0.5)'), 'hsl' (CSS string like 'hsl(120, 50%, 50%)'), 'hex' (lowercase hex like '#1a2b3c'), 'HEX' (uppercase hex like '#1A2B3C'), '{rgb}' (object {r: 255, g: 99, b: 71}), '{rgba}' (object {r: 255, g: 99, b: 71, a: 1}), '[rgb]' (array [255, 99, 71]), '[rgba]' (array [255, 99, 71, 255]).

Bun.color example [rgb] array output

Bun.color('red', '[rgb]') returns [255, 0, 0]. Bun.color('hsl(0, 0%, 50%)', '[rgb]') returns [128, 128, 128]. These inputs produce [255, 0, 0]: 0xff0000, {r: 255, g: 0, b: 0}, [255, 0, 0].

Bun.color example HEX uppercase output

Bun.color('red', 'HEX') returns '#FF0000'. Bun.color('hsl(0, 0%, 50%)', 'HEX') returns '#808080'. These inputs produce '#FF0000': 0xff0000, {r: 255, g: 0, b: 0}, [255, 0, 0].

Bun.color 'ansi' format auto-detection

The 'ansi' format detects the color depth of stdout from environment variables and automatically picks 'ansi-16m', 'ansi-256', or 'ansi-16' accordingly. If stdout doesn't support any form of ANSI color, it returns an empty string.

Bun.color return value on parse failure

If the input to Bun.color is unknown or fails to parse, the function returns null.

HTMLRewriter input type examples

Example showing different input types for HTMLRewriter: rewriter.transform(new Response("<div>content</div>")); rewriter.transform("<div>content</div>"); rewriter.transform(new TextEncoder().encode("<div>content</div>").buffer); rewriter.transform(new Response(new Blob(["<div>content</div>"]))); rewriter.transform(new Response(Bun.file("index.html")));

HTMLRewriter overview and input types

HTMLRewriter transforms HTML documents using CSS selectors. It is based on Cloudflare's lol-html. It accepts Response, string, ArrayBuffer, Blob (wrapped in Response), and File (wrapped in Response) as input types. The Cloudflare Workers implementation only supports Response objects.

HTMLRewriter.on() method with element handlers

The on(selector, handlers) method registers handlers for HTML elements matching a CSS selector. Handlers can define element(element), text(text), and comments(comment) functions that run for each matching element during parsing. Handlers can be asynchronous and return a Promise, pausing transformation until the Promise settles. Handlers still run one at a time in document order.

HTMLRewriter element attribute methods

Element attribute methods in HTMLRewriter: setAttribute(name, value) sets an attribute, getAttribute(name) retrieves an attribute value, hasAttribute(name) checks if an attribute exists, and removeAttribute(name) removes an attribute. All methods return the element instance for chaining.

HTMLRewriter element content manipulation methods

Element content methods: setInnerContent(content) sets inner content and escapes HTML by default; setInnerContent(content, { html: true }) parses HTML; before(content) inserts before the element; after(content) inserts after the element; prepend(content) inserts as first child; append(content) appends as last child. All support { html: true } option. All methods return the element for chaining.

HTMLRewriter element removal methods

Element removal in HTMLRewriter: remove() removes the element and all its contents; removeAndKeepContent() removes only the element tags but keeps the content inside.

HTMLRewriter element properties

HTMLRewriter element properties: tagName returns the lowercase tag name; namespaceURI returns the element's namespace URI; selfClosing is a boolean indicating if the element is self-closing (e.g. <div />); canHaveContent is a boolean indicating if the element can contain content (false for void elements like <br>); removed is a boolean indicating if the element was removed.

HTMLRewriter element attributes iteration

HTMLRewriter elements support iterating over attributes using: for (const [name, value] of el.attributes) { /* ... */ }

HTMLRewriter onEndTag method

The onEndTag(callback) method on elements handles the end tag. The callback receives an endTag object with methods: before(content) inserts before the end tag, after(content) inserts after the end tag, remove() removes the end tag, and a name property containing the tag name in lowercase.

HTMLRewriter text node operations

Text nodes in HTMLRewriter have: text property for the text content, lastInTextNode boolean indicating if this is the last chunk, removed boolean indicating if text was removed. Methods: before(content) inserts before text, after(content) inserts after text, replace(content) replaces the text, remove() removes the text. All support { html: true } option and return the text instance for chaining.

HTMLRewriter comment operations

Comment nodes in HTMLRewriter have: text property for comment content (readable and writable), removed boolean indicating if comment was removed. Methods: before(content), after(content), replace(content), remove(). All support { html: true } option and return the comment instance for chaining.

HTMLRewriter.onDocument() method

The onDocument(handlers) method registers handlers for document-level events. Handlers can define: doctype(doctype) with properties name, publicId, systemId; text(text) for text nodes; comments(comment) for comments; end(end) called at document end with end.append(content, options) to append content.

HTMLRewriter CSS selector support

HTMLRewriter supports CSS selectors: tag selectors (p), class selectors (p.red), ID selectors (h1#header), attribute selectors (p[data-test], p[data-test="one"], p[data-test="one" i] case-insensitive, p[data-test="one" s] case-sensitive, p[data-test~="two"] word match, p[data-test^="a"] starts with, p[data-test$="1"] ends with, p[data-test*="b"] contains, p[data-test|="a"] dash-separated), combinators (div span descendant, div > span direct child), pseudo-classes (p:nth-child(2), p:first-child, p:nth-of-type(2), p:first-of-type, p:not(:first-child)), and universal selector (*).

HTMLRewriter async handler behavior with string and ArrayBuffer

When transform(string) or transform(ArrayBuffer) is called with an async handler that requires the event loop (timers, I/O, fetch), it throws TypeError immediately. A handler whose Promise settles within a microtask checkpoint (no event loop needed, including process.nextTick and already-resolved Promises) still works with transform(string). Pass a Response to transform() when handlers might await real work.

HTMLRewriter transform() error handling

For string/ArrayBuffer input, transform() throws synchronously for: invalid selector syntax, invalid input types, body already used errors, and errors from content handlers. For Response input, transform() returns immediately and errors surface on the output body instead, including handler errors, rejected Promises, malformed input, stream errors, and memory allocation failures. Detached Promise rejections go to process-global unhandledRejection.

HTMLRewriter Response transformation behavior

When transforming a Response, the status code, headers, and other response properties are preserved. The body is transformed while maintaining streaming capabilities. Content-encoding like gzip is handled automatically. The original response body is marked as used after transformation. Headers are cloned to the new response.

HTMLRewriter basic rickroll example

Example showing HTMLRewriter usage: const rewriter = new HTMLRewriter().on("img", { element(img) { img.setAttribute("src", "https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg"); img.before('<a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank">', { html: true }); img.after("</a>", { html: true }); img.setAttribute("alt", "Definitely not a rickroll"); } }); const html = `<html><body><img src="/cat.jpg"><img src="dog.png"><img src="https://example.com/bird.webp"></body></html>`; const result = rewriter.transform(html);

HTMLRewriter async element handler example

Example of async element handler: rewriter.on("div", { async element(element) { const fragment = await fetch("https://example.com/fragment").then(r => r.text()); element.setInnerContent(fragment, { html: true }); } });

HTMLRewriter error handling example with Response

Example of error handling with Response: try { const output = await rewriter.transform(new Response(html)).text(); } catch (error) { console.error("a handler failed:", error); }

HTMLRewriter async handler microtask limitation

Example showing TypeError when async handler needs event loop with string input: new HTMLRewriter().on("div", { async element(element) { await Bun.sleep(1000); } }).transform("<div></div>"); throws: TypeError: HTMLRewriter.transform() cannot synchronously return a string because a content handler returned a Promise that did not resolve within a microtask. Pass a Response instead and await its body

Bun.JSON5.stringify() - convert JavaScript value to JSON5 string

Bun.JSON5.stringify() converts a JavaScript value to a JSON5 string. It accepts a second parameter (replacer, typically null) and a third parameter for space (indentation). The space parameter can be a number (spaces count) or a string (indent character). Unlike JSON.stringify, it preserves special numeric values like Infinity and NaN.

JSON5 supported features in Bun

Bun's JSON5 parser supports: comments (single-line // and multi-line /* */), trailing commas in objects and arrays, unquoted keys (valid ECMAScript 5.1 identifiers), single-quoted strings in addition to double-quoted, multi-line strings using backslash line continuations, hex numbers (0xFF), leading and trailing decimal points (.5 and 5.), Infinity and NaN (positive and negative), and explicit plus sign (+42).

JSON5 parser conformance in Bun

Bun's JSON5 parser is written in Rust and passes 100% of the official JSON5 test suite.

Bun.JSON5.parse() example with JSON5 features

Example showing Bun.JSON5.parse() with JSON5 features: ```ts import { JSON5 } from "bun"; const data = JSON5.parse(`{ // JSON5 supports comments name: 'my-app', version: '1.0.0', debug: true, // trailing commas are allowed tags: ['web', 'api',], }`); console.log(data); // { // name: "my-app", // version: "1.0.0", // debug: true, // tags: ["web", "api"] // } ```

Bun.JSON5.stringify() example with pretty printing

Example showing Bun.JSON5.stringify() with space parameter for pretty printing: ```ts import { JSON5 } from "bun"; const pretty = JSON5.stringify( { name: "my-app", debug: true, tags: ["web", "api"], }, null, 2, ); console.log(pretty); // { // name: 'my-app', // debug: true, // tags: [ // 'web', // 'api', // ], // } ``` The space argument can also be a string like "\t" for tab indentation.

JSON5.parse() error handling

Bun.JSON5.parse() throws a SyntaxError if the input is invalid JSON5. Wrap calls in try-catch to handle parsing errors.

JSON5.stringify() special value handling

Unlike JSON.stringify, JSON5.stringify preserves special numeric values. It outputs Infinity, -Infinity, and NaN as-is in the JSON5 string.

Bun.JSON5.parse() - parse JSON5 string to JavaScript value

Bun.JSON5.parse() parses a JSON5 string into a JavaScript value. It is imported from the 'bun' module. If the input is invalid JSON5, it throws a SyntaxError.

Bun.JSONL.parseChunk() error recovery

Unlike parse(), parseChunk() does not throw on invalid JSON. Instead, it returns the error in the error property, along with any values that were successfully parsed before the error. The read property indicates the position up to the last successful parse.

Bun.JSONL.parse() basic usage

Bun.JSONL.parse() parses a complete JSONL (newline-delimited JSON) input and returns an array of all parsed values. Each line in the input must be a separate JSON value. The input can be a string or a Uint8Array. When Uint8Array input is used, Bun automatically skips a UTF-8 BOM at the start of the buffer.

Bun.JSONL.parse() error handling

If the input contains invalid JSON and no values were successfully parsed, Bun.JSONL.parse() throws a SyntaxError. If at least one value was parsed before the error, the parsed values are returned without throwing.

Bun.JSONL.parse() with Uint8Array

Bun.JSONL.parse() accepts Uint8Array as input in addition to strings. Example: const buffer = new TextEncoder().encode('{"a":1}\n{"b":2}\n'); const results = Bun.JSONL.parse(buffer); // [{ a: 1 }, { b: 2 }]

Bun.JSONL.parseChunk() for streaming

Bun.JSONL.parseChunk() parses as many complete JSON values as it can from input and reports how far it got, enabling incremental parsing from network streams or other sources. It returns an object with properties: values (any[]), read (number of bytes or characters consumed), done (boolean indicating if entire input consumed), and error (SyntaxError or null).

Bun.JSONL.parseChunk() return object properties

The parseChunk() method returns an object with four properties: 'values' (type: any[], description: Array of successfully parsed JSON values), 'read' (type: number, description: Number of bytes for Uint8Array or characters for strings consumed), 'done' (type: boolean, description: true if entire input consumed with no remaining data), 'error' (type: SyntaxError | null, description: Parse error or null if no error occurred).

Bun.JSONL.parseChunk() with byte offsets

When input is a Uint8Array, parseChunk() accepts optional start and end byte offset parameters: Bun.JSONL.parseChunk(buf, start) or Bun.JSONL.parseChunk(buf, start, end). The read value returned is always a byte offset into the original buffer, suitable for use with TypedArray.subarray() for zero-copy streaming.

JSONL supported value types

Each line in JSONL input can be any valid JSON value, not just objects. This includes primitives (numbers, strings, booleans, null) and collections (arrays, objects).

Bun.JSONL.parse() example with multiple records

Example showing parsing multiple records: import { JSONL } from "bun"; const input = '{"id":1,"name":"Alice"}\n{"id":2,"name":"Bob"}\n{"id":3,"name":"Charlie"}\n'; const records = JSONL.parse(input); // [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }, { id: 3, name: "Charlie" }]

Give your agent this brain