Documentation
App Store screenshots
Capture listing screenshots from Simulator at App Store Connect sizes; keep
drafts under store/. Companion to testflight.md. Full ship
path: app-store.md.
One-minute path
walnut screenshots init .
walnut screenshots slots
walnut simulator --device "iPhone 16 Pro Max"
# Navigate to the screen you want, then:
walnut screenshots capture . --name 01-home --slot iphone-6-9
walnut screenshots check .
Layout
Created by walnut screenshots init:
store/
README.md
screenshots/
raw/<slot>/01-home.png # simctl capture
framed/<slot>/ # optional marketing frames
metadata/
subtitle.txt
promotional-text.txt
description.txt
keywords.txt
whats-new.txt
Upload to App Store Connect
walnut store upload .
# → patches description / keywords / promotional text / subtitle
# → replaces screenshots for each slot under store/screenshots/raw/
| Flag | Role |
|---|---|
--locale en-US | Localization (default en-US) |
--version 1.0 | ASC version string (default: marketing_version) |
--skip-metadata | Screenshots only |
--skip-screenshots | Copy only |
--dry-run | Print actions; no ASC writes |
Requires the same Team ASC API key as TestFlight (walnut device login). Creates the iOS
version + locale if missing. First versions often reject whatsNew until a prior release
exists — walnut retries without it.
Screenshots for slot iphone-6-9 upload as ASC display type APP_IPHONE_67 (Apple’s API
has no APP_IPHONE_69 enum yet; 1320×2868 is accepted there).
Happy path for a new listing:
walnut screenshots init .
walnut simulator . --device "iPhone 16 Pro Max"
walnut screenshots capture . --name 01-home --slot iphone-6-9
# edit store/metadata/*
walnut screenshots check .
walnut testflight .
walnut store upload .
Git
| Path | In git? | Notes |
|---|---|---|
store/README.md | Yes | Layout for humans |
store/metadata/*.txt | Yes | Listing copy (reviewable) |
store/screenshots/**/*.png (and jpg/webp/heic) | No | Root .gitignore — regenerate with walnut screenshots capture |
store/screenshots/**/.gitkeep | Yes | Keeps empty slot folders |
Do not force-add screenshot binaries unless you have a deliberate reason (e.g. LFS golden fixtures). Default is: metadata travels with the app; pixels are local artifacts.
Slots
walnut screenshots slots prints portrait sizes and preferred Simulator names:
| Slot id | Size (px) | Typical sim |
|---|---|---|
iphone-6-9 | 1320×2868 | iPhone 16 Pro Max |
iphone-6-7 | 1290×2796 | iPhone 15 Pro Max |
iphone-6-5 | 1284×2778 | iPhone 11 Pro Max |
ipad-13 | 2064×2752 | iPad Pro 13-inch (M4) |
Apple’s required set changes over time — prefer 6.9" for new iPhone apps.
check fails the process if PNGs don’t match the slot (portrait or landscape swap).
Commands
| Command | Role |
|---|---|
walnut screenshots init [dir] | Scaffold store/ |
walnut screenshots capture [dir] --name <slug> [--slot] [--device] | Boot sim (if needed) + simctl io booted screenshot |
walnut screenshots check [dir] | Validate pixel sizes under raw/ |
walnut screenshots slots | Print slot table |
Flags for capture: --settle <ms> (default 800) after boot before shooting.
Why not Fastlane?
Fastlane snapshot + deliver is a fine Ruby stack for large orgs. Walnut already
owns compile → TestFlight; screenshots are a thin simctl + size check + store/
convention so every app gets the same layout without a second toolchain. When ASC
API upload lands, it will write into this same tree — not a Fastlane lane file.
Related
- app-store.md — publish through App Review + release
- testflight.md — IPA upload
- device.md — physical install
- Skill: app-store-screenshots (framing, metadata, quality bar)