Bonsai

March 8, 2026 ยท View on GitHub

Bonsai

Bonsai

An HTML minifier in pure Swift.

Zero dependencies, comprehensive test suite (149 tests ported from html-minifier-next), replicates the output of html-minifier-next with the following options:

html-minifier-next optionNotes
caseSensitive: truePreserves tag and attribute name case
collapseBooleanAttributes: trueAlso handles draggable, crossorigin, contenteditable
collapseWhitespace: trueInline/block-aware smart collapsing
removeComments: trueKeeps <!--! --> bang comments and conditional comments
removeEmptyAttributes: trueclass, id, style, title, lang, dir, value, event handlers
removeRedundantAttributes: trueDefault values, script language/charset, a[name] matching id
removeScriptTypeAttributes: trueRemoves type="text/javascript" and variants
removeStyleLinkTypeAttributes: trueRemoves type="text/css" from <style> and <link>
useShortDoctype: trueAll doctypes become <!doctype html>

Usage

Include Bonsai in your Package.swift:

let package = Package(
  dependencies: [
    .package(url: "https://github.com/loopwerk/Bonsai", from: "1.0.0"),
  ],
  targets: [
    .target(
      name: "MyProject",
      dependencies: ["Bonsai"]),
  ]
)

Using it is a simple import and function call:

import Bonsai

let result = Bonsai.minifyHTML("<html>")

There are no options or settings to configure.

Performance

Benchmarked on a ~143 KB HTML page (1000 iterations, release build), using a M1 Max Macbook Pro:

ToolAvg time per operationThroughput
html-minifier (Node.js)12.1 ms83 ops/sec
html-minifier-terser (Node.js)14.3 ms70 ops/sec
html-minifier-next (Node.js)0.6 ms1,817 ops/sec
Bonsai (Swift)0.9 ms1,149 ops/sec

The speed difference between Bonsai and html-minifier-next only becomes noticeable at scale; for individual pages, both finish under a millisecond.

To run the benchmark yourself:

# Swift (release mode)
swift run -c release BonsaiBenchmark