Prism Inspector

Measure SwiftUI layout while it runs.

Prism Inspector reads a running app — in the iOS Simulator or on an iPhone plugged into your Mac — and lets you work on it the way you work in a design tool: click an element to inspect it, ⌥-click a second one to measure the space between them, and see immediately when that space is not on your design system's scale.

macOS 13 or later · Apple silicon and Intel · Free · Signed with Developer ID and notarized by Apple

Prism Inspector showing a running iOS shop screen: the view hierarchy on the left with each element named, the live screen in the middle with rulers, and the accessibility reading of the screen on the right.

The same app, live: the simulator on the right, the inspector reading it on the left. Two rows selected, the gap measured at 42 pt — and flagged 42→40, because 42 is not on this project's spacing scale.

What it does

Everything below is a screenshot of the tool doing the thing, against a real app running in the simulator — so what you measure is what the app actually rendered, not a guess from a picture of it.

Two elements selected on a running checkout screen: the items card and the delivery estimate, with the 16-point gap between them marked on the canvas, their combined size shown as 361 by 240, and the horizontal gap flagged in red for being off the spacing scale.

Measure like a design tool

Click an element to select it. ⌥-click a second one to measure the space between them — the gap per axis, or the four insets when one contains the other.

Distances come from the layout the app actually produced, in points. Nothing is counted by eye off a screenshot.

The design check: seven components of a checkout screen matched against their design, with the differences labelled on the canvas and listed beside it — the Place order button is 44 points tall where the design says 52.

Check the screen against the design

Attach a design and get a per-node report: what moved, what is the wrong size, what is missing. Expected positions are drawn straight onto the canvas, beside where the element actually landed.

When something has no match, the nearest unclaimed element is offered with it — because "it moved" and "it disappeared" look identical to a comparison that only matches by position, and only one of them is the bug you are looking for.

The accessibility reader listing what VoiceOver would say for a shop screen, in reading order, each product announced as one phrase with its name and price.

Hear what VoiceOver hears

Play the screen back in the order VoiceOver reads it, with each element outlined on the canvas as its announcement is spoken and highlighted in the list.

An unlabelled button stops being something you audit for and becomes something you notice: it is the one that says "Button" and nothing else. Trait words come from the traits SwiftUI already set, so they are what a real user would hear — in the reading language you pick, which is separate from the interface language.

A product card's image tile selected on a shop screen. The inspector's On its own section shows two pictures side by side: Alone, a plain blue gradient, and On screen, the same gradient with a white headphones glyph on it — so the glyph is a child, not part of the tile.

See a component on its own

On screen, a component covered by another, one at zero opacity and one with no height all look the same: like nothing at all. They are three different bugs.

Select anything and see it drawn by itself, next to the same patch of the screen. A blank picture is an answer too — it means the component draws nothing and everything you see in it belongs to its children.

The shop screen exploded into stacked planes seen from an angle: the full screen at the back, then rows and cards stepping forward, with the product image tiles floating in front of their containers.

Pull the screen apart

The components stacked in depth by how deeply they are nested, and orbitable. Each plane is drawn without the ones inside it, so a container that only holds other views reads as empty — which is exactly what it contributes.

Crop a flat screenshot instead and every container arrives painted with its children, which stacks into a pile of paper rather than a hierarchy. That is why this is built on renders from the app rather than on the picture.

The inspector's Live values section with a Screen margin slider at 34.4, a Title text field and a Shows search toggle. On the canvas the screen title and search field have moved inwards to match the new margin.

Change a value and watch it re-lay-out

Sizes can be pushed from here into any measured view. For padding, copy and flags the app offers them itself — one modifier hands over the binding it already owns.

The app really re-lays-out: text rewraps, everything below moves, and the measurements follow. It is not a drawing on top of a screenshot.

Prism Inspector with layout columns drawn over a running checkout screen as vertical bands, each measured at 78 points wide, with the column, gutter and margin settings beside them.

Your grid, over the running app

Lay your own columns across the live screen — count, gutter and margin as you set them — with the safe area beside them, at real device size rather than in a mockup.

The spacing is the scale you already committed in .prismkit.json, not a fixed 8 points. What you eyeball against here is the same number the design check and the MCP server judge by, so the grid you look at and the grid that fails a review cannot drift apart.

Prism Inspector drawing concentric corner rings over a running checkout screen, stepping inward from the device's 55 point radius in 16 point steps, with a card's corner sitting off the ring.

Concentric corners that actually nest

Nested corners look right when their radii step evenly inward from the one the hardware gives you, and wrong in a way most people feel without being able to name. Draw the rings and the corner that drifted stops being a hunch.

The rings start from the device's own radius, read from the simulator rather than guessed at, so they move when you change device instead of quietly describing a phone you stopped designing for.

Your spacing scale, not ours

Paddings and gaps are flagged when they fall off your scale, with the nearest token as the hint. It lives in a .prismkit.json you commit, so the app, the MCP server and the whole team judge by the same numbers.

No instrumentation required

Point it at a running app and inspect the view tree straight away. The SDK is optional — it upgrades readings from UIKit's class names to the component names you chose.

Mockup side by side

Put a design image beside the running app, overlay it with adjustable opacity, or wipe between the two — with the guides mirrored across both.

Rulers and guides

Rulers along the top and left; drag out of one to place a guide. Every layer is off by default, so the canvas starts clean and you turn on only what you are looking for.

Export and save sessions

Export the canvas exactly as you see it at native device scale, or save a session and review it later with the simulator closed.

Six languages

English, Spanish, Portuguese, Chinese, French and German — interface, help and the accessibility reader.

Get started

Four steps and you are measuring. Two of them are in your app: the inspector reads what the SDK streams, so an app without it has nothing to show.

  1. Install it

    Download the disk image, then drag Prism Inspector into Applications in the Finder. Dragging matters: copied any other way, macOS runs it from a randomised read-only folder and it can never update itself.

  2. Add the package to your app

    In Xcode: File ▸ Add Package Dependencies… and paste the repository URL. Or in a Package.swift:

    .package(url: "https://github.com/zalazara/PrismKit-SDK.git", from: "0.2.0")

    It compiles out of release builds entirely — the collection, overlay and streaming code is not in the shipping binary, so it does not need wrapping in #if DEBUG.

  3. Add one modifier at the root

    This is what streams. Nothing else in your app needs annotating:

    import PrismKit
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .measureScope()
        }
    }

    Put it above your NavigationStack or TabView so every screen you push is covered by it.

  4. Run it, and open Prism Inspector

    Launch in the simulator from Xcode or simctl, or plug in an iPhone and run it there — an attached device shows up in the same menu, by name. The inspector finds the app and mirrors its screen. Click anything to inspect it, ⌥-click a second element to measure between them.

    Order does not matter — start either one first, the app reconnects within a few seconds. If the view tree stays empty, the simulator has not built its accessibility tree yet: the inspector has a button for that, then relaunch the app.

Read the docs

Built for AI agents too

An MCP server ships inside the app bundle, so an agent can read the same measurements you see and report what does not match the design — no separate install, no server to run.

The design it compares against is a neutral description — a Figma node, a Pencil document or an agent's own words all arrive in the same shape, so nothing here is tied to one design tool.

The SDK is optional — and open

PrismKit is the Swift package you add to your app when you want measurements named after your components instead of after UIKit's internals.

dependencies: [
    .package(url: "https://github.com/zalazara/PrismKit-SDK.git", from: "0.2.0")
]

Free, and it opens without warnings.

Signed with Developer ID and notarized by Apple. macOS 13 or later.

Download for macOS