[![Build](https://github.com/swhitty/SwiftDraw/actions/workflows/build.yml/badge.svg)](https://github.com/swhitty/SwiftDraw/actions/workflows/build.yml) [![CodeCov](https://codecov.io/gh/swhitty/SwiftDraw/graphs/badge.svg)](https://codecov.io/gh/swhitty/SwiftDraw) [![Platforms](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fswhitty%2FSwiftDraw%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/swhitty/SwiftDraw) [![Swift 6.0](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fswhitty%2FSwiftDraw%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/swhitty/SwiftDraw) # Introduction **SwiftDraw** displays SVG images natively in SwiftUI, UIKit and AppKit. It includes a pure-Swift SVG parser and renderer, plus a command-line tool for converting SVGs to PNG, PDF, custom SF Symbols and Swift source code. - [Usage](#usage) - [SwiftUI](#swiftui) - [Loading and Transforming SVGs](#loading-and-transforming-svgs) - [UIKit](#uikit) - [AppKit](#appkit) - [Command Line Tool](#command-line-tool) - [Installation](#installation) - [SF Symbol](#sf-symbol) - [Alignment](#alignment) - [Swift Code Generation](#swift-code-generation) - [Credits](#credits) ## Usage ### SwiftUI `SVGView` works much like SwiftUI’s built-in `Image` view: ```swift import SwiftDraw SVGView("sample.svg") ``` By default, the SVG is rendered at its intrinsic size. To make it flexible within layouts, mark it as resizable: ```swift SVGView("sample.svg") .resizable() .scaledToFit() ``` `SVGView` works just like `Image`: - `.scaledToFit()` to scale proportionally so the SVG fits inside its container. - `.scaledToFill()` to fill the entire container, cropping if necessary. - `.resizable(resizingMode: .tile)` to repeat the SVG as tiles across the available space. SVGs can also be rendered as templates, replacing every non-transparent pixel with the current foreground style: ```swift SVGView("spider.svg") .renderingMode(.template) .foregroundStyle( LinearGradient( colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing ) ) ``` | `.original` | `.template` | |:-----------:|:-----------:| | Spider SVG rendered using original mode | Spider SVG rendered with a blue-to-purple gradient using template mode | When loading by name, `SVGView` maintains an internal cache for efficient repeated lookups. For more predictable performance (avoiding cache lookups or parsing), you can pass in an already-constructed `SVG` instance: ```swift var image: SVG var body: some View { SVGView(svg: image) } ``` Remote SVGs can be loaded using `AsyncSVGView`: ```swift AsyncSVGView(url: URL(string: "https://example.com/image.svg")) .resizable() .scaledToFit() ``` For custom loading and error states, use the phase-based initializer: ```swift AsyncSVGView(url: url) { phase in switch phase { case .empty: ProgressView() case .success(let svg): SVGView(svg: svg) case .failure: Image(systemName: "exclamationmark.triangle") } } ``` ### Loading and Transforming SVGs SVG images can be loaded and rasterized to `UIImage` or `NSImage`: ```swift let svg = SVG(named: "sample.svg", in: .main)! imageView.image = svg.rasterize() ``` Transformations can be added before rasterizing: ```swift let svg = SVG(named: "fish.svg")! // 100x100 .expanded(left: 10, right: 10) // 120x100 .scaled(2) // 240x200 imageView.image = svg.rasterize() // 240x200 ``` ### UIKit Create a `UIImage` directly from an SVG within a bundle, `Data` or file `URL`: ```swift import SwiftDraw let image = UIImage(svgNamed: "sample.svg") ``` ### AppKit Create an `NSImage` directly from an SVG within a bundle, `Data` or file `URL`: ```swift import SwiftDraw let image = NSImage(svgNamed: "sample.svg") ``` ## Command line tool The command line tool converts SVGs to other formats: PNG, JPEG, SFSymbol and Swift source code. ``` copyright (c) 2026 Simon Whitty usage: swiftdraw [--format png | pdf | jpeg | swift | sfsymbol] [--size wxh] [--scale 1x | 2x | 3x] svg file to be processed Options: --format format to output image: png | pdf | jpeg | swift | sfsymbol --size size of output image: 100x200 --scale scale of output image: 1x | 2x | 3x --insets crop inset of output image: top,left,bottom,right --precision maximum number of decimal places --output optional path of output file --hide-unsupported-filters hide elements with unsupported filters. Available keys for --format swift: --api api of generated code: swiftui | appkit | uikit Available keys for --format sfsymbol: --insets alignment of regular variant: top,left,bottom,right | auto --size size category to generate: small, medium large. (default is small) --ultralight svg file of ultralight variant --ultralight-insets alignment of ultralight variant: top,left,bottom,right | auto --ultralight-stroke-width auto-generate ultralight variant by scaling regular stroke-width: 0.5 | 50% --black svg file of black variant --black-insets alignment of black variant: top,left,bottom,right | auto --black-stroke-width auto-generate black variant by scaling regular stroke-width: 2.0 | 200% --legacy use the original, less precise alignment logic from earlier swiftdraw versions. ``` ```bash $ swiftdraw simple.svg --format png --scale 3x ``` ```bash $ swiftdraw simple.svg --format pdf ``` #### Resolving relative dimensions When the root `` uses percent values (`width="100%"`) or omits `width`/`height` entirely, SwiftDraw cannot determine the canvas size from the file alone. In those cases provide an explicit canvas size with `--size`, which acts as the viewport that percent values resolve against and as a fallback when both `width`/`height` and `viewBox` are missing: ```bash $ swiftdraw responsive.svg --format png --size 800x600 ``` If the SVG already declares a `viewBox`, missing `width`/`height` fall back to its dimensions automatically and `--size` is not required. ### Installation You can install the `swiftdraw` command-line tool on macOS using [Homebrew](http://brew.sh/). Assuming you already have Homebrew installed, just type: ```bash $ brew install swiftdraw ``` To update to the latest version once installed: ```bash $ brew upgrade swiftdraw ``` Alternatively download the latest command line tool [here](https://github.com/swhitty/SwiftDraw/releases/latest/download/SwiftDraw.dmg.zip). ### SF Symbol Custom SF Symbols can be created from a single SVG. SwiftDraw expands strokes, winds paths using the [non-zero rule](https://en.wikipedia.org/wiki/Nonzero-rule) and aligns elements generating a symbol that can be imported directly into Xcode.
$ swiftdraw [key.svg](https://github.com/swhitty/SwiftDraw/blob/main/Samples.bundle/key/key.svg) --format sfsymbol
Optional variants `--ultralight` and `--black` can also be provided:
$ swiftdraw [key.svg](https://github.com/swhitty/SwiftDraw/blob/main/Samples.bundle/key/key.svg) --format sfsymbol --ultralight [key-ultralight.svg](https://github.com/swhitty/SwiftDraw/blob/main/Samples.bundle/key/key-ultralight.svg) --black [key-black.svg](https://github.com/swhitty/SwiftDraw/blob/main/Samples.bundle/key/key-black.svg)
#### Alignment By default, SwiftDraw automatically sizes and aligns the content to the template guides. The auto alignment insets are output by the tool: ```bash $ swiftdraw simple.svg --format sfsymbol --insets auto Alignment: --insets 30,30,30,30 ``` Insets can be provided in the form `--insets top,left,bottom,right` specifying a `Double` or `auto` for each edge: ```bash $ swiftdraw simple.svg --format sfsymbol --insets 40,auto,40,auto Alignment: --insets 40,30,40,30 ``` Variants can also be aligned using `--ultralightInsets` and `--blackInsets`. #### Auto-generated weight variants When matching ultralight or black SVGs are not available, SwiftDraw can synthesize them from the regular SVG by scaling every `stroke-width` value before strokes are expanded. Both decimal and percent forms are accepted: ```bash $ swiftdraw key.svg --format sfsymbol \ --ultralight-stroke-width 50% \ --black-stroke-width 2.0 ``` Notes: - An explicit `--ultralight` or `--black` SVG always wins over the matching `--*-stroke-width` flag. A warning is printed if both are supplied. - The scaler walks element attributes, inline styles, and `