nano-svg: An SVG parser for icons

[ graphics, library, mit ] [ Propose Tags ] [ Report a vulnerability ]

Parse static SVG icons and vector artwork for geometry renderers, rasterizers and UI toolkits.

Reads UTF-8 ByteString input using hexml for XML and flatparse for attribute values. Returns a flat array of shapes in paint order, each with absolute path segments, a transform and a resolved style. Rendering and viewport mapping are left to the caller.

Gradients, patterns, text, masks, clipping paths, filters and CSS stylesheets are not supported. See Graphics.NanoSvg for supported features and limitations.


[Skip to Readme]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1.0.0, 0.2.0.0
Change log CHANGELOG.md
Dependencies base (>=4.17 && <4.23), bytestring (>=0.11.1 && <0.13), containers (>=0.6 && <0.9), flatparse (>=0.5 && <0.6), hexml (>=0.3.5 && <0.4), primitive (>=0.9 && <0.10) [details]
Tested with ghc ==9.14.1
License MIT
Author goolord
Maintainer zacharyachurchill@gmail.com
Uploaded by goolord at 2026-09-27T02:31:25Z
Category Graphics
Home page https://github.com/goolord/nano-svg
Bug tracker https://github.com/goolord/nano-svg/issues
Source repo head: git clone https://github.com/goolord/nano-svg.git
Distributions
Downloads 8 total (8 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for nano-svg-0.2.0.0

[back to package description]

nano-svg

A fast SVG parser for Haskell. Bytes in, a flat array of shapes out.

For geometry renderers, rasterizers and UI toolkits that need SVG icons and static vector artwork as paths. The library parses and normalizes geometry; the caller handles rendering and viewport mapping.

Quick start

parseSvg :: ByteString -> Either String Document reads UTF-8 SVG directly from a strict ByteString—no text-decoding step needed.

import Graphics.NanoSvg
import qualified Data.ByteString as BS

main :: IO ()
main = do
  bytes <- BS.readFile "clock.svg"
  case parseSvg bytes of
    Left err -> putStrLn err
    Right doc -> print (documentSize doc, length (documentShapes doc))

A Document contains the viewport size, the viewBox and a SmallArray of Shapes in paint order. Each shape carries its path, the Matrix that maps it into the viewBox, and its resolved Style. Relative path commands, shorthands and basic shapes become a common set of absolute path segments. The renderer walks segments without resolving an SVG tree, style inheritance or a transform stack. It still tracks the current point and subpath start.

encodeSvg :: Document -> ByteString writes a document back out as SVG, one path per shape; svgBuilder gives the same as a bytestring Builder. Parsing the result gives back the same shapes.

SVG scope

Supports paths, rectangles, circles, ellipses, lines, polylines and polygons; groups and use references; fills, strokes and inline styles; and SVG transforms. The focus is the static geometry used in icons and vector assets.

Not supported: gradients, patterns and other paint servers; text; clipPath, mask and filter; marker; CSS in a style element or an external sheet, and so class selectors; animation; and preserveAspectRatio, which is left to the renderer.

Unknown elements are skipped along with their children. Group opacity is multiplied into each shape rather than preserved as a compositing group. Nested svg and referenced symbol elements do not establish viewports.

Modules

Module Purpose
Graphics.NanoSvg parseSvg and encodeSvg, re-exporting the two below
Graphics.NanoSvg.Types the document model and matrix helpers
Graphics.NanoSvg.Attribute standalone parsers for paths, transforms, colors, numbers and lengths

Build

cabal build
cabal test
cabal haddock --open