GRAPHKIT 1.0.13

Graph layout, native in SwiftUI.

GraphKit runs nine layout engines, including dot, neato and circo, inside your app, and draws the result in a SwiftUI view, without a web view or a server.

GraphKit's own architecture, laid out by GraphKit. Press a key to change the engine.

Install

Your license includes GraphKit.xcframework as a download. Add it to your app target in Xcode, or reference it from a Swift package:

.binaryTarget(name: "GraphKit", path: "Frameworks/GraphKit.xcframework")
iOS17 or later
macOS14 or later
visionOS2.4 or later
ArchitectureApple silicon (arm64) only
Swift6
UISwiftUI GraphView

Build a graph in Swift and lay it out.

Add nodes and edges, pick an engine, and read back the computed geometry.

import GraphKit

// Create a graph
let graph = Graph(name: "MyGraph")

// Add nodes
let nodeA = try graph.addNode("A", attributes: NodeAttributes(
    shape: .circle,
    fillColor: "lightblue"
))
let nodeB = try graph.addNode("B", attributes: NodeAttributes(
    shape: .box,
    fillColor: "lightgreen"
))

// Add edges
try graph.addEdge(from: nodeA, to: nodeB, attributes: EdgeAttributes(
    style: .dashed,
    color: "red"
))

// Apply layout
try await graph.applyLayout(algorithm: .dot)

// Access geometry
print("Graph size: \(graph.size)")
print("Node A position: \(nodeA.frame)")

Then, in SwiftUI:

struct ContentView: View {
    @State private var graph = Graph()

    var body: some View {
        GraphView(graph)
            .task {
                let a = try! graph.addNode("A", attributes: .primary)
                let b = try! graph.addNode("B", attributes: .secondary)
                try! graph.addEdge(from: a, to: b)
                try! await graph.applyLayout(algorithm: .dot)
            }
    }
}
Output of the code on the left, rendered by GraphKit.

Nine layout engines behind one call.

Every engine takes the same graph through applyLayout(algorithm:). Six are Graphviz 14.1.4 and three are written in Swift.

dot

Hierarchical, layered. The default.

.dot

neato

Spring model.

.neato

fdp

Force-directed placement.

.fdp

sfdp

Scalable force-directed, for large graphs.

.sfdp

circo

Circular.

.circo

twopi

Radial.

.twopi

dagre

Layered (Sugiyama), in Swift.

.dagre

tidy

Non-layered tidy tree, in Swift.

.tidyTree

radial

Concentric-ring radial tree, in Swift.

.radialTree

Also in Swift: two mind-map layouts and a grid layout.

Big graphs off the main thread.

How a large graph gets into your view, drawn by GraphKit.
  1. GraphKit's public API is isolated to the main actor, the same as SwiftUI.
  2. For large graphs, build a Sendable GraphPlan on a background task, then apply it on the main actor in one validated step.
  3. Layout requests are serialized at the Graphviz bridge. A newer request supersedes an older one that's still in flight.

One-time license.

14-day money-back guarantee if GraphKit doesn't work as described and we can't fix it. Payments run through Paddle.

DiagramKit ships with GraphKit inside, licensed for use through DiagramKit only. To use GraphKit directly, you need a GraphKit license.

Buy a license

Notices

Next: An Android version, built on the same Graphviz core with Jetpack Compose, is in the works.