Skip to main content

Bakeshot

Capture the same UI your users see — without a simulator or a device.

https://github.com/user-attachments/assets/6a902e87-bb5d-467f-8c55-96d89f550ac3

Without Bakeshot

Getting the screens you want means installing the app, opening the right screen, getting it into the right state, placing the widget, configuring it, getting real data into it — and only then taking the shot.

The screenshot you want What you or your agent has to do first
A home screen with a month of history Seed the database, or tap the data in by hand
A seven-day streak Use the app for seven days running — or forge the dates in storage
The paid tier, active Set up a StoreKit sandbox account and buy through it
An empty state, an error state Wipe the data, or cut the network, and hope nothing else changes
A chart that looks good Keep re-seeding until the numbers happen to make a nice shape
The same shots in five languages Change the device language and take every shot again, five times
A widget Install the app, add the widget, configure it, get data into it, then photograph the home screen and crop

And you do all of it again next release.

With Bakeshot

You describe the state in code; Bakeshot builds your app, runs it on your Mac as a real iOS binary, and draws the view.

shotBoth("home") { HomeView().environmentObject(thirtyDaysOfHistory()) }
shot("paywall", dark: true) { PlusSheet().environmentObject(PlusStore(active: true)) }

Nothing is simulated or mocked up: these are your real views, your real fonts and assets, rendered by iOS. The app never has to reach the state — the state is handed to it.

It does not decorate. Backgrounds, captions and device frames are somebody else's job (try app-store-screenshots). Bakeshot does the part nobody has automated: the real UI, in the state that sells it.

Use it

pip install git+https://github.com/Ryoheihoriuchi0000/bakeshot
cd MyApp
bakeshot init

Then tell your coding agent:

Bakeshot を使って App Store Connect 用のプロモーション画像を作成して — or, in English, "use Bakeshot to create the promotional images for App Store Connect"

init installs a skill into .claude/skills/bakeshot/, so the agent reads your models and views, writes the scene script, runs the render, fixes whatever crashed, and tells you where the images are. You do not have to learn the flags, or the file, or any of this README.

Not using Claude Code?

Point any agent at the skill: "Read .claude/skills/bakeshot/SKILL.md and follow it." Or drive it yourself: edit Bakeshot/Scenes.swift, then bakeshot bake --locale ja --locale en.

PNGs land in Bakeshot/out/<locale>/, at real store dimensions.

The scene script

Bakeshot/Scenes.swift is where you say what to shoot and in what state. It is plain Swift against your own types, which is why an agent can write it:

enum BakeshotScenes {
    @MainActor static var scenes: [BakeshotScene] {
        [
            shotBoth("home_busy") { HomeView().environmentObject(busyStore()) },
            shot("paywall", dark: true) { PlusSheet().environmentObject(PlusStore()) },
            shotBoth("widget", size: .widgetMedium) { MyWidgetView(entry: demoEntry()) },
        ].flatMap { $0 }
    }
}

@MainActor private func busyStore() -> AppStore {
    let s = AppStore()
    s.tags = [Tag(name: "Study"), Tag(name: "Workout"), Tag(name: "Work")]
    s.logs = (0..<20).map { LogEntry(minutes: 30 + $0 * 5) }
    return s
}

An empty app makes a worthless screenshot. The state is the product.

Does it touch my project?

No. Bakeshot never edits your files, your .xcodeproj, or your git history.

To render your views it needs one test target hosted by your app. Rather than add that to your project, it works on a hidden throwaway copy of the .xcodeproj, and deletes it when the run ends — including when the run fails. Nothing is left behind.

What actually happens
  1. Copy MyApp.xcodeproj → .MyApp-bakeshot.xcodeproj (hidden, temporary, sits next to the original because Xcode projects reference their files by relative path).
  2. Add a test target to the copy, hosted by your app.
  3. Build the copy for My Mac (Designed for iPad) — your iOS binary, running on macOS, so Firebase, UIKit, your fonts and assets are all the real thing.
  4. Render each scene with UIHostingController + drawHierarchy, write PNGs.
  5. Delete the copy.

Requirements

  • Apple silicon Mac with Xcode
  • gem install --user-install xcodeproj
  • Your app must be signable with your own team — the setup you already build with

bakeshot init checks all of this and tells you what is missing.

Price

Everything above is free: every screen, every state, every language, every device size.

Public free, forever — app screens
Widgets $49 / year
Team / agency $199 / year — several projects, CI
Launch offer $99 once, first 100 buyers

The version you paid for keeps working forever; renewing buys the next year of updates. Xcode breaks this kind of tool roughly once a year — that is what the renewal pays for.

Known limits

  • Xcode is driven while baking, so you cannot use Xcode during a run. (xcodebuild test cannot launch an iOS-on-Mac test host; the IDE can.)
  • Screens that need network, keychain or a live account crash while rendering. Bakeshot names them and bakes the rest — give them fakes in the scene script.
  • Widget sources are compiled into the test bundle, so a widget that depends on the extension's own asset catalog may render without those images.

License

MIT

Metadata

Release files for bakeshot 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bakeshot 0.1.0
File Size Uploaded
bakeshot-0.1.0.tar.gz 37.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bakeshot 0.1.0
File Interpreter ABI Platform
bakeshot-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 76.7 kB

Release files / bakeshot-0.1.0.tar.gz

Download URL bakeshot-0.1.0.tar.gz
Size 37.8 kB
Tags Source
SHA-256 checksum
How to use checksums
e0e2e26821d5d665aad4930a3e3bd652c662477903e31d76b265f3406b196357
BLAKE2b-256 checksum
How to use checksums
d3fd53a13b01936abccf00b978214c9da20abe3377327ec38abc9f80a8a8897e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / bakeshot-0.1.0-py3-none-any.whl

Download URL bakeshot-0.1.0-py3-none-any.whl
Size 38.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
365cedc704f2fd747ba037ad4f5e14e60cc4937adf31861e113a49d1e55c95c6
BLAKE2b-256 checksum
How to use checksums
bdd62c5b6529b9aea646b9356da7a1c3dc8180e4e6004dd8e7bf974b8e3233af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page