RepoPilotOpen in app →

exyte/Macaw

Powerful and easy-to-use vector graphics Swift library with SVG support

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • 13 active contributors
  • Distributed ownership (top contributor 34% of recent commits)
  • MIT licensed
Show 3 more →
  • CI configured
  • Tests present
  • Stale — last commit 2y ago

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/exyte/macaw)](https://repopilot.app/r/exyte/macaw)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/exyte/macaw on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: exyte/Macaw

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/exyte/Macaw shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • 13 active contributors
  • Distributed ownership (top contributor 34% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Stale — last commit 2y ago

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live exyte/Macaw repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/exyte/Macaw.

What it runs against: a local clone of exyte/Macaw — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in exyte/Macaw | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 853 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>exyte/Macaw</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of exyte/Macaw. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/exyte/Macaw.git
#   cd Macaw
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of exyte/Macaw and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "exyte/Macaw(\\.git)?\\b" \\
  && ok "origin remote is exyte/Macaw" \\
  || miss "origin remote is not exyte/Macaw (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "Macaw.xcodeproj/project.pbxproj" \\
  && ok "Macaw.xcodeproj/project.pbxproj" \\
  || miss "missing critical file: Macaw.xcodeproj/project.pbxproj"
test -f "Dependencies/SWXMLHash/XMLHash.swift" \\
  && ok "Dependencies/SWXMLHash/XMLHash.swift" \\
  || miss "missing critical file: Dependencies/SWXMLHash/XMLHash.swift"
test -f "Macaw.podspec" \\
  && ok "Macaw.podspec" \\
  || miss "missing critical file: Macaw.podspec"
test -f "MacawTests/MacawSVGTests.swift" \\
  && ok "MacawTests/MacawSVGTests.swift" \\
  || miss "missing critical file: MacawTests/MacawSVGTests.swift"
test -f "Example/Example/MenuViewController.swift" \\
  && ok "Example/Example/MenuViewController.swift" \\
  || miss "missing critical file: Example/Example/MenuViewController.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 853 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~823d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/exyte/Macaw"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Macaw is a Swift library for rendering and animating vector graphics with native SVG parsing and drawing support. It provides a declarative API to programmatically create shapes, paths, groups, and animations that render to UIView/NSView using Core Graphics, avoiding the need for web views or custom rasterization. Monolithic framework structure: core drawing engine in src/ (inferred from Swift file count), SVG parsing via embedded SWXMLHash in Dependencies/SWXMLHash/, two parallel example apps (Example-macOS/ and Example/ for iOS) showcasing animations, shapes, morphing, SVG loading, and easing. CI via .travis.yml, dependency management via Cartfile.

👥Who it's for

iOS and macOS developers building apps that need vector graphics rendering, SVG import capabilities, or shape-based animations without resorting to web views. Common use cases: custom charts, icon systems, animated illustrations, and SVG asset pipelines.

🌱Maturity & risk

This project is deprecated as of the latest README — the maintainers explicitly recommend using SwiftUI for new work and SVGView (exyte/SVGView) for SVG-specific needs. However, it remains stable and will receive updates for Xcode compatibility. The codebase is substantial (~565K Swift lines) with example projects for both iOS and macOS, suggesting it was production-grade before deprecation.

High risk for new projects: the README explicitly states no new features or bug fixes will be added, only Xcode compatibility updates. The project is in maintenance-only mode. Dependency risk is minimal (only SWXMLHash embedded in Dependencies/), but the single-maintainer governance and deprecation stance mean community forks are necessary for active development.

Active areas of work

The project is in maintenance mode. No active development visible; the deprecation notice dominates. The maintainers explicitly encourage forks and community-driven PRs for bug fixes. Users should expect minimal new work beyond Xcode version compatibility.

🚀Get running

Clone the repo, open Example/Example.xcworkspace (iOS) or Example-macOS/Example-macOS.xcworkspace (macOS) in Xcode. Dependencies are managed via Carthage (see Cartfile) — run carthage bootstrap --platform iOS (or macOS) before opening. Build and run the example app to see shapes, animations, SVG loading, and event handling in action.

Daily commands: Open Example/Example.xcworkspace, select iPhone simulator or device scheme, ⌘R to build/run. For macOS: open Example-macOS/Example-macOS.xcworkspace, select Example-macOS scheme, ⌘R.

🗺️Map of the codebase

  • Macaw.xcodeproj/project.pbxproj — Primary Xcode project configuration defining all build targets (iOS, macOS) and dependencies for the vector graphics library
  • Dependencies/SWXMLHash/XMLHash.swift — Core XML parsing dependency used throughout SVG parsing and element deserialization
  • Macaw.podspec — CocoaPods specification defining the library's public API, platform support, and dependency constraints
  • MacawTests/MacawSVGTests.swift — Primary test suite validating SVG parsing and rendering correctness across the library
  • Example/Example/MenuViewController.swift — Entry point demonstrating all major features (animations, shapes, morphing, filters) for new contributors
  • .swiftlint.yml — Code style enforcement configuration that all contributors must follow

🧩Components & responsibilities

  • SVG Parser (SWXMLHash, Swift) — Loads SVG file, deserializes XML elements, extracts geometric and stylistic properties, builds shape tree
    • Failure mode: Malformed SVG or unsupported elements silently skip or render with defaults
  • Shape Renderer (Core Graphics, Core Animation) — Converts Macaw shape objects to Core Graphics drawing commands, applies fills/strokes, manages z-order
    • Failure mode: Complex shapes or many nodes may cause frame drops; no pixel-perfect guarantees
  • Animation Engine (CADisplayLink, NSTimer) — Manages animation state, easing functions, frame scheduling, combines/sequences multiple animations

🛠️How to make changes

Add a New Shape Type

  1. Create a new shape example view that extends the base shape rendering system with your custom geometry (Example/Example/Examples/Shapes/ShapesExampleView.swift)
  2. Add test cases validating bounds calculation and render output for the new shape (MacawTests/Bounds/NodeBoundsTests.swift)
  3. Register the new shape in the menu navigation system (Example/Example/MenuViewController.swift)

Add Animation to Existing Shape

  1. Create animation properties (duration, easing, delay) following the pattern in existing animation examples (Example/Example/Examples/Animations/AnimationsView.swift)
  2. Implement the animation update logic using the timing framework (MacawTests/Animation/AnimationUtilsTests.swift)
  3. Add test case for animation lifecycle and state transitions (MacawTests/Animation/CombineAnimationTests.swift)

Support New SVG Element

  1. Extend XML deserialization logic in the SWXMLHash dependency layer (Dependencies/SWXMLHash/XMLIndexer+XMLIndexerDeserializable.swift)
  2. Add parsing rules to convert SVG element attributes to Macaw primitives (MacawTests/MacawSVGTests.swift)
  3. Test with sample SVG file and validate rendering matches expected output (Example/Example/Assets/SVG/tiger.svg)

Add New Interactive Feature

  1. Implement event handling logic following the existing gesture and touch pattern (Example/Example/Examples/Events/EventsExampleController.swift)
  2. Create visual example demonstrating the feature with clear state feedback (Example/Example/Examples/Filters/FiltersViewController.swift)
  3. Add feature to the main menu for discoverability (Example/Example/MenuViewController.swift)

🔧Why these technologies

  • Swift — Native iOS and macOS language enabling type-safe vector graphics API with direct platform integration
  • Core Graphics / Core Animation — Native Apple framework for hardware-accelerated vector rendering and smooth frame-rate animations
  • SWXMLHash — Lightweight Swift XML parser for SVG document deserialization without external dependencies
  • CocoaPods / Carthage — Package managers enabling easy integration as a dependency in other iOS/macOS projects

⚖️Trade-offs already made

  • Embedded XML parser (SWXMLHash) vs system XMLParser

    • Why: Provides Swift-idiomatic deserialization and type safety over native API
    • Consequence: Adds ~50KB to library size but eliminates Objective-C bridge complexity
  • Declarative animation API vs imperative CoreAnimation

    • Why: Simplifies animation composition (sequences, combinations, morphing) for users
    • Consequence: Small overhead in animation scheduling, but dramatically improves developer experience
  • iOS + macOS dual support vs single platform

    • Why: Maximizes addressable market for vector graphics library
    • Consequence: Maintains two separate example projects and build configurations

🚫Non-goals (don't propose these)

  • Real-time collaborative editing of vector graphics
  • 3D vector graphics or WebGL rendering
  • Server-side SVG rasterization or headless rendering
  • Complete SVG 2.0 specification compliance (subset support)
  • Lossy compression or vector quantization

🪤Traps & gotchas

Deprecation gotcha: PRs are merged rarely and selectively; expect slow or no response on new feature requests. Xcode version constraint: .swift-version file pins Swift version — mismatches cause build failures. Carthage dependency management: unlike CocoaPods, Carthage requires manual carthage bootstrap before opening .xcworkspace — missing this is the #1 build error. Example workspace split: iOS and macOS examples are separate workspaces (Example/ vs Example-macOS/) — don't mix them. No test suite visible: the file list shows no Tests/ directory, so changes require manual validation via example apps.

🏗️Architecture

💡Concepts to learn

  • Scene Graph — Macaw renders via a hierarchical tree of shapes, groups, and transforms — understanding scene graphs is essential to manipulating geometry in this library
  • SVG (Scalable Vector Graphics) — The entire SVG parsing pipeline (Dependencies/SWXMLHash/) exists to convert SVG XML into Macaw shapes — you must understand SVG coordinate systems and path syntax
  • Core Graphics (Quartz 2D) — Macaw renders all vector geometry via Core Graphics calls on iOS/macOS — knowing CGPath, CGContext, and CGTransform is essential for debugging rendering
  • Core Animation — Macaw's animation system backs onto CABasicAnimation and CAKeyframeAnimation — understanding CADisplayLink and timing functions is required for smooth animations
  • Affine Transform — Shape rotation, scaling, and translation all use 2D affine matrices (CGAffineTransform) — the transform example (Example/.../Transform/) demonstrates this core concept
  • XML Parsing / Deserialization — SVG files are XML; SWXMLHash converts them to Macaw types — XMLIndexer+XMLIndexerDeserializable.swift shows custom Decodable patterns for hierarchical data
  • exyte/SVGView — Spiritual successor to Macaw for SVG-only workflows — the maintainers officially recommend this for new SVG-heavy projects
  • apple/swift-docc — Modern documentation generation for Swift packages — Macaw lacks API docs and could benefit from DocC markup
  • Carthage/Carthage — Dependency manager used by Macaw (see Cartfile) — understanding Carthage workflows is required to build this project locally
  • realm/realm-swift — Similar age/maturity trajectory as a pre-SwiftUI era framework; shows how mature iOS libraries handle stability and deprecation
  • alibaba/Tangram-iOS — Parallel declarative graphics framework for iOS, now also in maintenance mode — good reference for comparing architectures and deprecation patterns

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive SVG parsing unit tests for Dependencies/SWXMLHash

The repo includes SWXMLHash as a dependency (Dependencies/SWXMLHash/XMLHash.swift, XMLIndexer+XMLIndexerDeserializable.swift) which is critical for SVG parsing. There's no visible test suite for XML parsing edge cases, despite SVG support being a core feature. Tests should cover malformed SVG, namespace handling, and attribute extraction to prevent regressions.

  • [ ] Create Tests/SVGParsing/ directory structure
  • [ ] Add unit tests for Dependencies/SWXMLHash/XMLHash.swift covering element hierarchy parsing
  • [ ] Add tests for Dependencies/SWXMLHash/XMLIndexer+XMLIndexerDeserializable.swift focusing on deserialization
  • [ ] Test real SVG files from Example-macOS/Example-macOS/Assets/SVG/tiger.svg and Example/Example/Assets/SVG/tiger.svg
  • [ ] Add edge case tests: invalid XML, missing namespaces, empty elements

Create GitHub Actions CI workflow to replace .travis.yml

The repo uses outdated Travis CI (.travis.yml). Migrate to GitHub Actions for faster, more integrated CI/CD. This workflow should test both Example and Example-macOS targets across Swift versions defined in .swift-version, and run SwiftLint (.swiftlint.yml exists but is not enforced in CI).

  • [ ] Create .github/workflows/swift-ci.yml with matrix testing for iOS and macOS platforms
  • [ ] Reference .swift-version for Swift version matrix compatibility
  • [ ] Add SwiftLint step using .swiftlint.yml configuration
  • [ ] Add build steps for both Example/Example.xcodeproj and Example-macOS/Example-macOS.xcodeproj
  • [ ] Add Carthage build test (Cartfile and Cartfile.resolved exist but aren't validated in CI)

Document SVG feature support and limitations in README with examples from Example-macOS

The README snippet shows this is a vector graphics library with SVG support, but there's no detailed feature matrix. The file structure shows multiple SVG example controllers (Example-macOS/Examples/SVG/SVGExampleViewController.swift) and example SVG files, but no corresponding documentation of which SVG elements/attributes are supported, which transform features work, or known limitations.

  • [ ] Extract and document SVG element support from source code parsing logic
  • [ ] Create FEATURES.md or SVG_SUPPORT.md documenting: supported elements (path, circle, rect, etc.), transforms, gradients, filters
  • [ ] Add cross-references to Example-macOS/Examples/SVG/ and Example/Example/Examples/SVG/ in README
  • [ ] Include code example showing how to load tiger.svg from Example/Example/Assets/SVG/tiger.svg
  • [ ] Document known SVG limitations (e.g., unsupported filters, animation constraints)

🌿Good first issues

  • Add unit tests for SVG parsing edge cases: the repo has no visible test suite. Pick Dependencies/SWXMLHash/XMLHash.swift and write tests for malformed SVG attributes (missing namespaces, invalid coordinate formats, etc.) — critical for stability.
  • Document the animation system with a new example: Example/Example/Examples/ has Animations/ and Easing/ subfolders, but no README explaining the difference or linking to API docs. Add a SwiftUI-style guide showing CABasicAnimation vs. Macaw's declarative animation API.
  • Fix SwiftLint warnings in Example code: the .swiftlint.yml is configured but the example files likely have style violations. Run swiftlint and fix warnings in Example-macOS/Example-macOS/Examples/ — good way to understand the codebase without changing core logic.

Top contributors

Click to expand
  • @ystrot — 34 commits
  • @f3dm76 — 30 commits
  • [@Petrov Anatoly](https://github.com/Petrov Anatoly) — 10 commits
  • [@Anton Poltoratskyi](https://github.com/Anton Poltoratskyi) — 6 commits
  • @mnndnl — 4 commits

📝Recent commits

Click to expand
  • 273964a — Update README.md (zapletnev)
  • 3622eaf — Update README.md (zapletnev)
  • e72ffc9 — Update README.md (zapletnev)
  • 9c087ea — Update README.md (ystrot)
  • a3ddf65 — Add deprecation image (ystrot)
  • 29ec199 — Merge pull request #781 from hotbott/master (ystrot)
  • 9797fb0 — Bump version (hotbott)
  • 96e4900 — Fix native image scale (hotbott)
  • 197903c — Add render dispose (hotbott)
  • d508348 — Bump version (f3dm76)

🔒Security observations

The Macaw library codebase shows a reasonable security posture as a graphics library with minimal external dependencies. However, the primary security concerns are: (1) bundled dependency management making vulnerability tracking difficult, (2) potential XXE and injection risks from SVG/XML parsing without visible input validation, and (3) lack of evident security-focused linting rules. The codebase does not appear to have hardcoded credentials or obvious injection vulnerabilities in the file structure. Recommendations focus on dependency management, input validation for SVG processing, and security-focused code analysis configuration.

  • Medium · Bundled Third-Party Dependency Without Version Control — Dependencies/SWXMLHash/. The codebase includes a bundled copy of SWXMLHash library in Dependencies/SWXMLHash/ directory. This approach makes it difficult to track updates, security patches, and creates maintenance burden. The bundled dependency may contain unpatched vulnerabilities. Fix: Use a dependency manager (CocoaPods, SPM, Carthage) to manage SWXMLHash as an external dependency with pinned versions. This allows for easier updates and vulnerability tracking.
  • Medium · SVG Parsing Without Input Validation — Dependencies/SWXMLHash/XMLHash.swift, SVG parsing logic. The library processes SVG files (e.g., Example/Example/Assets/SVG/tiger.svg) through XML parsing via SWXMLHash. SVG files can contain malicious content including XXE (XML External Entity) attacks, embedded scripts, or other payload attacks if not properly validated. Fix: Implement strict input validation for SVG files. Disable XXE processing in the XML parser, sanitize SVG content before rendering, and validate against a whitelist of allowed SVG elements and attributes.
  • Low · No Visible Security Configuration — .swiftlint.yml. The .swiftlint.yml configuration file is present but typical security-focused linting rules (unsafe patterns, hardcoded credentials detection) are not evident in the file structure analysis. Fix: Configure SwiftLint with security-focused rules to detect: hardcoded secrets, unsafe string operations, and other security anti-patterns. Add rules like 'force_unwrap', 'force_cast', etc.
  • Low · Example Applications May Not Follow Security Best Practices — Example/, Example-macOS/. Multiple example applications are included in the repository (Example/, Example-macOS/) which may contain insecure code patterns that could be copied by users learning from these examples. Fix: Ensure all example code follows security best practices. Add comments highlighting secure coding patterns and explicitly warn against anti-patterns.
  • Low · Missing .gitignore Security Entries — .gitignore. While a .gitignore file exists, without reviewing its content, common sensitive files may be accidentally committed (e.g., .env, API keys in config files, IDE workspace settings with credentials). Fix: Ensure .gitignore includes entries for: .env files, local configuration files, IDE-specific files, build artifacts, and any files that might contain secrets. Consider using a pre-commit hook to catch sensitive data.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · exyte/Macaw — RepoPilot