f(x) = σ(Wx + b)∇loss.backward()model.predict(x)torch.nn.Transformerawait fetch('/api')git rebase -i HEAD~3docker compose up -dconsole.log('here')∫f(x)dx∑(i=0→n)O(log n)fn main() -> Result<>SELECT * FROM userskubectl get pods{ ...state, loading }npm run build && deploypipe(filter, map, reduce)env.PROD=true
Codse logo
  • Services
  • Work
  • OpenClaw
  • Blog
  • Home
  • Services
  • Work
  • OpenClaw
  • Blog

Get in touch

Let's build something

Tell us what you're working on. We'll scope it within 48 hours and propose a sprint or retainer that fits.

Quick links

ServicesWorkAI ReadinessOpenClawBlog

Also find us on

GithubFacebookInstagram
Codse© 2026 Codse
Software · AI Agents
App Development
Guides
App Store Optimization

App Store screenshot pipeline for Expo apps like Sisu

Codse Tech
Codse Tech
August 9, 2026

Manual App Store screenshots fall apart as soon as you add a second locale. Add iPad sizes, Devanagari line heights (Sisu teaches Nepali and English), and "hide anything that looks like debug chrome," and you end up with folders named final-final-2.

We built a repeatable pipeline while shipping Sisu and reuse it across Codse Expo apps: plant locale into the running simulator, capture real UI, frame marketing slides, map folders to App Store Connect locales, validate, then upload with asc — only when a human says go.

Pipeline diagram from simulator captures through framed marketing slides to App Store Connect upload

What done looks like

For each storefront locale and required device size:

Raw captures

Real in-app UI on simulator: correct language, Release build, seeded demo content, no Dev Client chrome.

Fancy frames

Device bezel plus localized headline copy, sized for the ASC device type.

Staged folders

Remapped to ASC locale codes (en → en-US, and so on) and checked for pixel size.

Validate, then upload

Local validate first. Upload with asc only on purpose — never as a side effect of regenerate.

Device targets we ship for Sisu-style universal apps:

ASC device typePixel size we aim forNotes
IPHONE_651242×2688Primary phone set
IPAD_PRO_3GEN_1292064×2752 (2048×2732 also accepted)Separate raw + fancy trees

Keep one product frame consistent across locales. Mixed bezels look accidental on the product page.

In-app locale is not store locale

This trips teams once.

In-appASC listing localeNotes
enen-USDefault storefront
en-GBen-GB
eses-ES
frfr-FR
ptpt-PTEuropean Portuguese unless you also ship pt-BR
hihi
nenoneNepali is in-app on Sisu — generate fancy for QA, do not upload as a storefront locale

Stage scripts should remap folders. Before asc screenshots upload, move ne/ aside so the CLI does not treat it as a child locale.

Shot bootstrap: language before first paint

Framing English UI and translating only the marketing headline is weak ASO. Shoppers see the UI inside the device.

We use a small bootstrap module (copy into each app) plus an allowlisted route file planted into the app container:

# Plant route + locale, then relaunch
./scripts/plant-shot-route.sh <sim-udid> /home ne light

Contract we keep stable across apps:

ParamAliasesEffect
lang / localene, en, es-ES, …Sets app locale
theme / appearancelight | dark | systemForces color scheme when the app supports it
pathallowlisted onlyNavigates to a known screen

Deep links work too (sisu://home?lang=ne). Disk planting is better for headless sims when Simulator.app is not open.

Rules that matter:

  • Allowlist routes. Never execute arbitrary paths from Documents/.
  • Apply locale (and theme) before navigate so the first paint is not an English flash.
  • Seed demo content the screens need (categories, sample words, illustrations) so every locale looks intentional.
  • Prefer a Release build on the shot sim. Expo Dev Client chrome in store art is an instant tell.

Capture → frame → stage → upload

1) Raw captures per locale

./scripts/seed-shot-content.sh <sim-udid>
./scripts/capture-raw-locale.sh ne
# or batch storefront langs:
./scripts/capture-all-store-locales.sh

Name raws by screen and variant (home.png, play.png, category.png, …). iPad is a parallel tree (raw-ipad/, separate sim UDID). Do not stretch iPhone captures and hope.

2) Fancy frames (koubou)

Marketing slides are HTML templates + YAML, rendered to device-sized PNGs.

./scripts/generate-fancy-all.sh      # iPhone 65
./scripts/generate-fancy-ipad.sh     # iPad 12.9 / 13

Before render we run layout calibration (@chenglou/pretext + node-canvas) so type sizes and device offsets keep comfortable air between copy and bezel per locale. Devanagari and long compounds will wreck a single global font size. Per-lang layout JSON fixes that without hand-nudging every PNG.

Frame colors should come from the product (Sisu's playful purple, not a generic AI gradient kit). One outcome per slide — screenshots sell, they do not document the whole app.

3) Stage for ASC + validate

bash ./scripts/stage-asc-screenshots.sh --validate
bash ./scripts/stage-asc-ipad.sh --validate

Staging remaps en → en-US, es → es-ES, and so on, and checks sizes. After every regenerate, spot-check a tall-script locale (ne / hi) and a long-copy locale: no text-on-device overlap, phone still visible, gaps look intentional.

4) Upload only on purpose

Keep upload disabled by default. When you are ready:

source .secrets/asc.sh
export APP_ID=…

mv screenshots/asc/iphone65/ne /tmp/ne-preview   # skip non-store locale

asc screenshots upload --app "$APP_ID" --version 1.0.7 \
  --path ./screenshots/asc/iphone65 \
  --device-type IPHONE_65 --replace

asc screenshots upload --app "$APP_ID" --version 1.0.7 \
  --path ./screenshots/asc/ipad129 \
  --device-type IPAD_PRO_3GEN_129 --replace

Same discipline for listing metadata: asc metadata validate locally; asc metadata push only after explicit OK.

Apple can OCR text in screenshot captions. Put real phrases there when they read naturally — keyword stuffing still looks like keyword stuffing.

After Xcode upgrades, re-check simulator UDIDs in your shot settings file. Stale UDIDs fail in confusing ways.

Layout agents (and humans) can follow

Put durable commands and locale maps in AGENTS.md. That file survives context loss better than chat history.

Suggested tree:

screenshots/raw/{lang}/
screenshots/raw-ipad/{lang}/
screenshots/koubou/           # templates, yaml, strings
screenshots/fancy/iphone65/{lang}/
screenshots/fancy/ipad129/{lang}/
screenshots/asc/iphone65/{asc-locale}/
screenshots/asc/ipad129/{asc-locale}/
scripts/plant-shot-route.sh
scripts/capture-*.sh
scripts/generate-fancy-*.sh
scripts/stage-asc-*.sh
src/platform/shot-bootstrap.ts

Secrets stay in .secrets/asc.sh. Never commit machine-absolute p8 paths in tracked config.

FAQ

Can I translate only the marketing frame and skip re-capturing the app?+

You can. It looks wrong. Shoppers see the UI inside the device. Re-plant locale and recapture raws when in-app strings change.

Why exclude Nepali from ASC upload?+

Nepali is not an App Store Connect listing locale. On Sisu we keep it for in-app QA and fancy previews, then move the staged folder aside before upload.

Do I need both iPhone and iPad sets?+

If the app is universal or iPad-capable, ship the required iPad sizes. Run a parallel capture + fancy path — do not stretch phone screenshots.

What is the fastest regenerate after a UI change?+

Recapture only the affected locales and screens, rerun fancy for those langs, restage, spot-check bezel gaps, then upload with --replace for that device type. Full-matrix runs are for major visual or copy passes.

Can I capture headless with Xcode-beta only?+

Yes. Point DEVELOPER_DIR at Xcode-beta, boot via simctl, plant routes on disk, and capture without assuming Simulator.app is open.

Ship the pipeline once, copy shot-bootstrap plus plant/capture/stage scripts into the next Expo app, and update the locale table. Screenshots become a checklist instead of a release blocker.

For the binary side of the same release week, see How we ship Sisu on Xcode Cloud.

App Store Optimization

Store listing and creative optimization when you want help shipping the locale matrix.

Explore service

Custom software

Expo apps with capture bootstrap and ASC upload scripts wired in from day one.

Explore service
app store screenshots
aso
expo
koubou
asc cli
localization
sisu