Self-hosted open-source App Store toolkit for indie iOS developers — keyword tracking, screenshot generation, video pipelines, PPO experiments, and Apple Search Ads optimization, all in one place. Pair it with Claude Code and you get an AI co-pilot that actually understands your App Store.
Stop paying $500–999/mo to Sensor Tower / AppTweak / SplitMetrics / SearchAds.com. ASO Studio runs on your machine, uses public APIs where possible, and stores everything locally.
ASO Studio is a monorepo of four connected tools sharing one origin (localhost:5173) with a top-left app switcher:
| Tool | Path | What it does |
|---|---|---|
| Keywords | / |
Per-keyword, per-locale rank tracking across 50+ countries. Snapshot engine, week-over-week deltas, competitor intelligence. |
| Screenshots / PPO | /studio/ |
App Store screenshot generator with AI hero enhancement (fal.ai gpt-image-2). Templates, scaffolds, headline overlays, locale translations. Multi-strategy A/B treatment generator for ASC PPO. |
| Video (beta) | /video/ |
UGC video pipeline for ad creative — script → voiceover → b-roll → captions. |
| ASA Ads (new) | /asa/ |
Apple Search Ads optimization — ROI projection, per-keyword bid intelligence, search-term cleanup, ASC trial cross-match, Telegram alerts. Self-hosted alternative to SearchAds.com. |
All four sub-tools share one Settings page and one local key vault.
What it does for your ASA campaigns:
- ROI projection — "spend $1000 on this keyword/campaign → expect N installs, M trials, $X revenue, Y% ROI". Honest about data quality:
WAIT · need 3 more daysinstead of fake numbers. - Bid intelligence — per-keyword recommendations with high/medium/low confidence. Bulk apply or one-click
−10% / +10% / → recommended. - Spend impact preview — every bid change opens a modal showing projected daily/weekly/monthly spend delta + ROI verdict before you confirm.
- Search terms cleanup — auto-suggests negatives (terms with taps but no installs) and discovery candidates (terms that converted but aren't in your keyword list).
- Geo heatmap + hero chart — see which countries are winners at a glance.
- Background sync — start sync, navigate to another tool, come back to see the progress bar still ticking.
- Telegram alerts — 🔥 Burn, 💸 High CPI,
⚠️ Stalled, 📈 Spend spike. - Multi-app — separate ROI/settings/recommendations per app.
- Settings auto-suggestion —
trial_to_paid_ratecomputed from real ASC events (Crossgrade from Introductory Offer+Billing Retry).
Full details: asa-ads/README.md (incl. how to drive it from an LLM via REST + SQLite).
ASO Studio is built to be driven by AI. Every editor state is a JSON file under ~/.aso-studio/ so an LLM agent can read/write it directly. Two MCP servers sit on top:
asc-mcp(dsm5e/nomly-asc-mcp) — full App Store Connect API: builds, versions, localizations, screenshots, in-app purchases, subscriptions, PPO experiments, custom product pages, reviews.apple-search-ads-mcp(AppVisionOS) — full Apple Ads (Search Ads) Campaign Management API v5: campaigns, ad groups, keywords, negative keywords, budget orders, reports.
What Claude can do for you (with these MCPs + this studio):
- 🤖 Audit your ASO — pull current title/subtitle/keywords across all locales, score them against competitors, suggest specific replacements.
- 🤖 Run keyword research — fetch competitor app metadata, analyze top apps for any keyword in any country, score difficulty/traffic ratios.
- 🤖 Generate App Store screenshots end-to-end — pick a preset, write headlines per locale, generate AI hero images, export PNGs for ASC.
- 🤖 Run PPO experiments — design 3 treatment concepts (palette / signature element / 3D break-out / story arc), generate 5-15 screens per concept, export ZIPs, create the ASC PPO experiment via API.
- 🤖 Launch Apple Search Ads campaigns — generate keyword lists from competitor research, set bids based on traffic/difficulty scores, create campaigns + ad groups + budget orders programmatically.
- 🤖 Run ASA Ads day-to-day — the ASA Ads sub-tool itself is agent-friendly (REST + SQLite). See
asa-ads/README.mdfor the full API surface and example workflows: audit campaigns, find waste, apply bid recommendations in bulk, monitor live via SSE. - 🤖 Track campaign performance — pull daily reports, surface wasted spend, suggest pause/scale/raise/lower-bid actions.
git clone https://github.com/dsm5e/aso-tracker.git aso-studio
cd aso-studio
npm install # registers all 4 workspaces
npm run dev # launches all 4 tools in parallel
# open http://localhost:5173All 4 tools share the same origin via the Keywords vite proxy:
| Tool | URL | Vite | API |
|---|---|---|---|
| Keywords | http://localhost:5173/ | 5173 | 5174 |
| Screenshots | http://localhost:5173/studio/ | 5180 | 5181 |
| Video | http://localhost:5173/video/ | 5190 | 5191 |
| ASA Ads | http://localhost:5173/asa/ | 5193 | 5194 |
First-time setup:
- Settings (gear icon, top-right) — paste API keys you have.
FAL_API_KEYis needed for AI image generation,OPENAI_API_KEYfor translations. - Keywords: empty dashboard → + Add your first app, paste your iTunes App ID, hit Test connection → Add app & start tracking.
- Snapshot: pick a locale, add 5-10 keywords, click Run snapshot — watch live progress.
- Screenshots / PPO: open the Studio tab → pick a preset → upload your simulator screenshots → write headlines or per-strategy prompts → generate.
TL;DR — keys never leave your machine. ASO Studio is a local-first tool. Every key you paste is stored in a single JSON file on your own filesystem, sent only to the upstream API it belongs to, and never to any backend we control (we don't run a backend at all).
The studio uses two third-party APIs for its AI features. Both are pay-per-use; you only pay for what you generate.
| Key | Required for | Free tier? | Where to get |
|---|---|---|---|
FAL_API_KEY |
AI image generation (gpt-image-2) — Screenshots hero, PPO renders, Polish | $1 free credit on signup; ~$0.05 per medium-quality render after | fal.ai/dashboard/keys |
OPENAI_API_KEY |
Locale translations of headlines (gpt-4o-mini) | $5 free credit on signup; ~$0.0001 per headline after | platform.openai.com/api-keys |
The Keywords tool (rank tracking) needs no API keys at all — it uses the public iTunes Search API.
~/.aso-studio/keys.json ← single file, JSON, mode 0600 (owner-only readable)
The 0600 permission means only your user account can read or write the file — not other users on the machine, not background processes running as different users. The studio's backend (aso-screenshots/server) is the only thing that opens this file, and it does so in-process (no network call).
When the studio needs a key, it resolves in this order:
- Environment variable (
FAL_API_KEY=...in your shell) — for CI / Docker / direct override ~/.aso-studio/keys.json— what the Settings UI writes to- Throw with a "configure key in Settings" message — never silently fails
In the Settings modal (gear icon, top-right):
- All inputs are
<input type="password">— your screen never displays the key while you're pasting it. - Click 👁 to reveal a draft (only the value you're typing right now, never an already-saved one).
- Once saved, the UI shows a masked preview (
fal_••••••AbCd) and never round-trips the full key back to the browser. - The "Clear" button removes the key from disk; env-var-set keys can't be cleared from the UI (clear the env var instead).
ASO Studio has no telemetry, no analytics, no crash reporter, no remote config. The only outbound network calls are:
- iTunes Search API (for app metadata + keyword ranks) — no auth, no keys
- fal.ai API (when you click "Generate") — only with your
FAL_API_KEY - OpenAI API (when you click "Translate") — only with your
OPENAI_API_KEY
There is literally no other backend in this stack.
Generated by the studio for Dream Journal: AI Meanings — three treatment concepts in different visual languages, all from the same source screenshots:
Each treatment uses a locked palette + atmosphere + lighting + signature element anchor across all 5-7 screens, with composition variance (tilt, framing distance, 3D break-out elements) telling a story arc through the set. Prompts authored conversationally with Claude; renders done in batch via fal.ai's gpt-image-2.
Three UGC ad creatives generated end-to-end by the video sub-tool — script → voiceover → b-roll selection → captions → endcard:
For AI agents working with this codebase, see llms-full.txt — full architectural context, file map, state schema, and command examples. Compatible with the llmstxt.org standard.
config/apps.json— your tracked apps (gitignored)config/keywords/*.json— your keyword lists per app (gitignored; only*.example.jsoncommitted)data/rankings.db— local SQLite with snapshot history (gitignored)~/.aso-studio/— keys, editor state, exports (outside the repo, mode 0600)
Nothing leaves your machine. You bring your own keywords, your own keys, your own creative.
- Frontend: React 19 + Vite + TypeScript
- Backend: Express + better-sqlite3 + Sharp (image processing)
- AI: fal.ai (gpt-image-2 for image edits), OpenAI (translations)
- Data source: public iTunes Search API (no keys), optional App Store Connect / Apple Ads APIs through their respective MCP servers (your own auth)
- Rate limit: conservative 2 workers × 500ms sleep → ~240 req/min (Apple's limit is ~500). Auto-abort + Resume on persistent 502.
npm run snapshot -- --app=dream # all locales for one app
npm run snapshot -- --app=dream --locales=us,tr,de
npm run snapshot # every app, every localeStreams line-by-line progress. Suitable for cron, CI, or Claude Code automation.
npm run migrate-jsonl -- /path/to/aso-rankings.jsonlTrack search phrases (2-4 words) — what real users type into App Store search. Not single words from the Keywords field in ASC.
Localize by intent, not literal translation. Example: Turkish users search rüya tabiri ("dream interpretation") — not rüya günlüğü ("dream journal").
MIT — see LICENSE.
Built in public as part of the Nomly indie portfolio.