Files
skills/plugins/document-navigator/docs/devtools/docs/compress-svg/README.md
2026-06-09 21:06:27 +01:00

15 KiB

@suaveplan/compress-svg - SVG optimisation and minification: whitespace removal, redundant attribute stripping, path data precision reduction, element collapsing, ID mangling, and SVGO-compatible plugin pipeline

Summary

SVG optimisation and minification for TypeScript. Pure TypeScript — no DOMParser, no external SVG library. Runs in Bun, Node.js, browsers, and edge runtimes.

Documentation tree

- [compress-svg](./src/core/compress-svg/compress-svg.md) — _(no submodules)_- [svg](./src/parser/svg/svg.md) — _(no submodules)_- [svg](./src/parser/svg/svg.md) — _(no submodules)_- [cleanup-attrs](./src/plugins/cleanup-attrs/cleanup-attrs.md) — _(no submodules)_- [cleanup-attrs](./src/plugins/cleanup-attrs/cleanup-attrs.md) — _(no submodules)_- [collapse-groups](./src/plugins/collapse-groups/collapse-groups.md) — _(no submodules)_- [collapse-groups](./src/plugins/collapse-groups/collapse-groups.md) — _(no submodules)_- [convert-path-data](./src/plugins/convert-path-data/convert-path-data.md) — _(no submodules)_- [convert-path-data](./src/plugins/convert-path-data/convert-path-data.md) — _(no submodules)_- [convert-transforms](./src/plugins/convert-transforms/convert-transforms.md) — _(no submodules)_- [convert-transforms](./src/plugins/convert-transforms/convert-transforms.md) — _(no submodules)_- [mangle-ids](./src/plugins/mangle-ids/mangle-ids.md) — _(no submodules)_- [mangle-ids](./src/plugins/mangle-ids/mangle-ids.md) — _(no submodules)_- [remove-comments](./src/plugins/remove-comments/remove-comments.md) — _(no submodules)_- [remove-comments](./src/plugins/remove-comments/remove-comments.md) — _(no submodules)_- [remove-doctype](./src/plugins/remove-doctype/remove-doctype.md) — _(no submodules)_- [remove-doctype](./src/plugins/remove-doctype/remove-doctype.md) — _(no submodules)_- [remove-metadata](./src/plugins/remove-metadata/remove-metadata.md) — _(no submodules)_- [remove-metadata](./src/plugins/remove-metadata/remove-metadata.md) — _(no submodules)_- [types](./src/types/common.md) — _(no submodules)_- [common](./src/types/common.md) — _(no submodules)_- [compress-svg](./src/core/compress-svg/compress-svg.md) — _(no submodules)_- [svg](./src/parser/svg/svg.md) — _(no submodules)_- [svg](./src/parser/svg/svg.md) — _(no submodules)_- [cleanup-attrs](./src/plugins/cleanup-attrs/cleanup-attrs.md) — _(no submodules)_- [cleanup-attrs](./src/plugins/cleanup-attrs/cleanup-attrs.md) — _(no submodules)_- [collapse-groups](./src/plugins/collapse-groups/collapse-groups.md) — _(no submodules)_- [collapse-groups](./src/plugins/collapse-groups/collapse-groups.md) — _(no submodules)_- [convert-path-data](./src/plugins/convert-path-data/convert-path-data.md) — _(no submodules)_- [convert-path-data](./src/plugins/convert-path-data/convert-path-data.md) — _(no submodules)_- [convert-transforms](./src/plugins/convert-transforms/convert-transforms.md) — _(no submodules)_- [convert-transforms](./src/plugins/convert-transforms/convert-transforms.md) — _(no submodules)_- [mangle-ids](./src/plugins/mangle-ids/mangle-ids.md) — _(no submodules)_- [mangle-ids](./src/plugins/mangle-ids/mangle-ids.md) — _(no submodules)_- [remove-comments](./src/plugins/remove-comments/remove-comments.md) — _(no submodules)_- [remove-comments](./src/plugins/remove-comments/remove-comments.md) — _(no submodules)_- [remove-doctype](./src/plugins/remove-doctype/remove-doctype.md) — _(no submodules)_- [remove-doctype](./src/plugins/remove-doctype/remove-doctype.md) — _(no submodules)_- [remove-metadata](./src/plugins/remove-metadata/remove-metadata.md) — _(no submodules)_- [remove-metadata](./src/plugins/remove-metadata/remove-metadata.md) — _(no submodules)_- [types](./src/types/common.md) — _(no submodules)_- [common](./src/types/common.md) — _(no submodules)_- [compress-svg](./src/core/compress-svg/compress-svg.md) — _(no submodules)_- [svg](./src/parser/svg/svg.md) — _(no submodules)_- [svg](./src/parser/svg/svg.md) — _(no submodules)_- [cleanup-attrs](./src/plugins/cleanup-attrs/cleanup-attrs.md) — _(no submodules)_- [cleanup-attrs](./src/plugins/cleanup-attrs/cleanup-attrs.md) — _(no submodules)_- [collapse-groups](./src/plugins/collapse-groups/collapse-groups.md) — _(no submodules)_- [collapse-groups](./src/plugins/collapse-groups/collapse-groups.md) — _(no submodules)_- [convert-path-data](./src/plugins/convert-path-data/convert-path-data.md) — _(no submodules)_- [convert-path-data](./src/plugins/convert-path-data/convert-path-data.md) — _(no submodules)_- [convert-transforms](./src/plugins/convert-transforms/convert-transforms.md) — _(no submodules)_- [convert-transforms](./src/plugins/convert-transforms/convert-transforms.md) — _(no submodules)_- [mangle-ids](./src/plugins/mangle-ids/mangle-ids.md) — _(no submodules)_- [mangle-ids](./src/plugins/mangle-ids/mangle-ids.md) — _(no submodules)_- [remove-comments](./src/plugins/remove-comments/remove-comments.md) — _(no submodules)_- [remove-comments](./src/plugins/remove-comments/remove-comments.md) — _(no submodules)_- [remove-doctype](./src/plugins/remove-doctype/remove-doctype.md) — _(no submodules)_- [remove-doctype](./src/plugins/remove-doctype/remove-doctype.md) — _(no submodules)_- [remove-metadata](./src/plugins/remove-metadata/remove-metadata.md) — _(no submodules)_- [remove-metadata](./src/plugins/remove-metadata/remove-metadata.md) — _(no submodules)_- [types](./src/types/common.md) — _(no submodules)_- [common](./src/types/common.md) — _(no submodules)_- [compress-svg](./src/core/compress-svg/compress-svg.md) — _(no submodules)_- [svg](./src/parser/svg/svg.md) — _(no submodules)_ - [svg](./src/parser/svg/svg.md) — _(no submodules)_- [cleanup-attrs](./src/plugins/cleanup-attrs/cleanup-attrs.md) — _(no submodules)_ - [cleanup-attrs](./src/plugins/cleanup-attrs/cleanup-attrs.md) — _(no submodules)_- [collapse-groups](./src/plugins/collapse-groups/collapse-groups.md) — _(no submodules)_ - [collapse-groups](./src/plugins/collapse-groups/collapse-groups.md) — _(no submodules)_- [convert-path-data](./src/plugins/convert-path-data/convert-path-data.md) — _(no submodules)_ - [convert-path-data](./src/plugins/convert-path-data/convert-path-data.md) — _(no submodules)_- [convert-transforms](./src/plugins/convert-transforms/convert-transforms.md) — _(no submodules)_ - [convert-transforms](./src/plugins/convert-transforms/convert-transforms.md) — _(no submodules)_- [mangle-ids](./src/plugins/mangle-ids/mangle-ids.md) — _(no submodules)_ - [mangle-ids](./src/plugins/mangle-ids/mangle-ids.md) — _(no submodules)_- [remove-comments](./src/plugins/remove-comments/remove-comments.md) — _(no submodules)_ - [remove-comments](./src/plugins/remove-comments/remove-comments.md) — _(no submodules)_- [remove-doctype](./src/plugins/remove-doctype/remove-doctype.md) — _(no submodules)_ - [remove-doctype](./src/plugins/remove-doctype/remove-doctype.md) — _(no submodules)_- [remove-metadata](./src/plugins/remove-metadata/remove-metadata.md) — _(no submodules)_ - [remove-metadata](./src/plugins/remove-metadata/remove-metadata.md) — _(no submodules)_- [types](./src/types/common.md) — _(no submodules)_ - [common](./src/types/common.md) — _(no submodules)_

Features

  • compressSvg — parse → plugin pipeline → multipass loop → serialize → CompressResult with size metrics
  • parseSvg / serializeSvg — standalone push-parser and compact serializer
  • 8 built-in plugins — removeComments, removeMetadata, removeDoctype, collapseGroups, cleanupAttrs, convertPathData, convertTransforms, mangleIds
  • 3 presets — PRESET_DEFAULT, PRESET_SAFE, PRESET_AGGRESSIVE
  • Plugin API — single apply(node, options): SvgNode | null contract; compose any plugins
  • OTel instrumentation — counter + duration + ratio histograms via @opentelemetry/api
  • Property-based tests — idempotency, parse↔serialize round-trip, ratio invariants

Installation

bun add @suaveplan/compress-svg

Quick Start

import { compressSvg } from '@suaveplan/compress-svg';

const result = compressSvg(svgString);
console.log(result.data);           // optimised SVG
console.log(result.ratio);          // e.g. 0.78
console.log(result.passCount);      // multipass iterations used

Presets

import { compressSvg, PRESET_DEFAULT, PRESET_SAFE, PRESET_AGGRESSIVE } from '@suaveplan/compress-svg';

// Default: removeComments + metadata + doctype + collapseGroups + cleanupAttrs + convertPathData
compressSvg(svg, { plugins: PRESET_DEFAULT });

// Safe: no ID mangling, no transform conversion
compressSvg(svg, { plugins: PRESET_SAFE });

// Aggressive: all plugins including mangleIds and convertTransforms
compressSvg(svg, { plugins: PRESET_AGGRESSIVE });

Custom Plugin

import type { SvgPlugin } from '@suaveplan/compress-svg';

const removeTitle: SvgPlugin = {
  name: 'removeTitle',
  apply(node) {
    return node.type === 'element' && node.name === 'title' ? null : node;
  },
};

compressSvg(svg, { plugins: [removeTitle, ...PRESET_DEFAULT] });

Options

compressSvg(svg, {
  plugins: PRESET_DEFAULT,    // override the full pipeline
  floatPrecision: 2,          // decimal places for path coords (default: 3)
  transformPrecision: 3,      // decimal places for transforms (default: 5)
  multipass: true,            // re-run until output is stable (default: true)
});

Modules

Import path Contents
@suaveplan/compress-svg All exports
@suaveplan/compress-svg/core/compress-svg compressSvg
@suaveplan/compress-svg/parser/svg-parser parseSvg, serializeSvg
@suaveplan/compress-svg/plugins/remove-comments removeComments
@suaveplan/compress-svg/plugins/remove-metadata removeMetadata
@suaveplan/compress-svg/plugins/remove-doctype removeDoctype
@suaveplan/compress-svg/plugins/collapse-groups collapseGroups
@suaveplan/compress-svg/plugins/cleanup-attrs cleanupAttrs
@suaveplan/compress-svg/plugins/convert-path-data convertPathData
@suaveplan/compress-svg/plugins/convert-transforms convertTransforms
@suaveplan/compress-svg/plugins/mangle-ids mangleIds, createMangleIds
@suaveplan/compress-svg/presets PRESET_DEFAULT, PRESET_SAFE, PRESET_AGGRESSIVE