Skip to content

Repository files navigation

AppShot

Free App Store & Google Play screenshot generator that runs entirely in your browser.

No signup. No upload. No watermark. No backend.

Try it live →

License: MIT PRs welcome Dependencies No tracking

The AppShot editor: device frame preview, template picker and style panel

What it does

Upload the raw screenshots you already took from the simulator, add a device frame and a headline, and download store-ready PNGs at the exact size Apple and Google require.

Three finished App Store screenshots exported from AppShot

Why another one

Most screenshot generators want an account before they'll show you anything, watermark the free tier, or upload your unreleased app designs to someone else's server. AppShot has no backend at all — there is nothing to sign up for and nowhere for your images to go.

AppShot Typical alternatives
Account required Never Usually, before you can export
Your images Stay in your browser Uploaded to their servers
Watermark None Common on free tiers
Cost Free, no tiers Freemium or subscription
Export sizes Exact, verified Usually correct
Alpha channel Stripped (see below) Often left in — App Store rejects these
Offline Works after first load No

Features

  • 26 device frames — iPhone 8 Plus through iPhone 16 Pro Max, iPad Air/Pro, Pixel, Galaxy and Surface. Drawn with canvas primitives, so there are no mockup image assets to download and "clay" frames can be recoloured.
  • Multi-size export — select as many devices as you need; one download gives you a ZIP with a folder per size. Presets cover exactly what each store requires.
  • 7 templates — Simple, Bold, Angled, Duo, Spotlight, Minimal and Full Bleed.
  • Edit text on the screenshot — click the headline directly on the preview and type. Headlines auto-shrink to fit; subheadlines are optional per screen.
  • Pixel-exact PNGs with no alpha channel — the single most common cause of App Store rejections, handled properly (see How it works).
  • Your work persists — settings and text in localStorage, images in IndexedDB. Close the tab and come back.
Template picker showing seven live thumbnails rendered with the user's own screenshot
Templates preview your actual screenshot, not stock art.
Multi-select device picker with store presets and search
Pick several sizes at once; presets match store requirements.

Quick start

git clone https://github.com/YOUR_USERNAME/appshot.git
cd appshot
npm install
npm run dev

Open http://localhost:5173.

npm run build     # typecheck, bundle, prerender all routes, emit sitemap + robots
npm run preview   # serve the production build locally

Requires Node 18+.

How it works

Three decisions carry most of the design.

One render function, two scales

renderSlide(canvas, slide, settings, image, scale) draws everything in export coordinates and applies ctx.setTransform(scale, 0, 0, scale, 0, 0). The preview calls it at ~0.22, the export calls it at 1, and template thumbnails call it at 0.055.

This is why the download always matches the preview exactly. Building the preview in HTML/CSS and screenshotting it with html2canvas is the usual approach, and the usual source of exports that don't look like what the user saw.

PNGs are encoded by hand, without an alpha channel

canvas.toBlob('image/png') always writes colour type 6 (RGBA), even when every pixel is opaque. App Store Connect rejects those with "Images can't contain alpha channels or transparencies" — after accepting the upload, so you only find out at the end.

src/lib/png.ts encodes colour type 2 (truecolour RGB) directly: read the pixels, drop the alpha byte, Paeth-filter the scanlines, deflate with the native CompressionStream. No library needed, and the files come out smaller than Chrome's encoder produces.

python3 -c "from PIL import Image; print(Image.open('screenshot.png').mode)"
# RGB   ← what the stores accept
# RGBA  ← what gets rejected

Device frames are drawn, not imported

Every frame is rounded rectangles, a notch/island/punch-hole and a home indicator, sized as fractions of the screen width. Adding a device is a single entry in src/data/devices.ts — no artwork, no licensing questions, and "clay" variants are just a different fill.

Prerendered for search engines

npm run build renders every route to static HTML with its own title, description, canonical URL and JSON-LD, then hydrates in the browser. Crawlers get full content without executing JavaScript; sitemap.xml and robots.txt are generated from the same route table so they can't drift.

Project structure

src/
├── lib/
│   ├── render.ts       the single render function — the heart of the app
│   ├── png.ts          alpha-free PNG encoder (colour type 2)
│   ├── export.ts       single PNG and multi-device ZIP export
│   ├── site.ts         routes + SEO metadata (one source of truth)
│   ├── router.tsx      ~60-line history router
│   ├── storage.ts      localStorage project persistence
│   └── imageCache.ts   IndexedDB blobs + decoded ImageBitmap cache
├── data/
│   ├── devices.ts      26 devices + store presets
│   └── templates.ts    7 template layouts
├── components/         Landing, Editor, pickers, marketing pages
└── entry-server.tsx    SSR entry used by the prerender step
scripts/prerender.mjs   static HTML + sitemap + robots generation
deploy/nginx.conf       production server block

Supported devices

All 26 devices and their export sizes

Export size is the PNG dimension each store expects — not necessarily the device's real screen resolution. Every Android device exports at 1080 × 1920 because that is Google Play's standard phone screenshot canvas.

Device Group Export size
Google Pixel 4 Android 1080 × 1920
Google Pixel 8 Pro Android 1080 × 1920
Google Pixel 8 Pro (clay) Android 1080 × 1920
Google Pixel 9 Pro Android 1080 × 1920
Google Pixel 9 Pro (clay) Android 1080 × 1920
Samsung Galaxy S10 Android 1080 × 1920
Samsung Galaxy S20 Android 1080 × 1920
Surface Pro Android 1080 × 1920
iPhone 8 Plus iPhone 1242 × 2208
iPhone 11 iPhone 828 × 1792
iPhone 11 (clay, thin) iPhone 1170 × 2532
iPhone 12 iPhone 1170 × 2532
iPhone 12 (no notch) iPhone 1170 × 2532
iPhone 13 Pro iPhone 1170 × 2532
iPhone 13 Pro Max iPhone 1284 × 2778
iPhone 14 Pro iPhone 1290 × 2796
iPhone 14 Pro (clay) iPhone 1290 × 2796
iPhone 15 Pro Max iPhone 1290 × 2796
iPhone 15 Pro Max (clay) iPhone 1290 × 2796
iPhone 16 Pro Max iPhone 1320 × 2868
iPhone 16 Pro Max (clay) iPhone 1320 × 2868
iPad Air 3rd Gen iPad 1668 × 2224
iPad Pro 3rd Gen iPad 2048 × 2732
iPad Pro 3rd Gen (clay) iPad 2048 × 2732
iPad Pro M4 iPad 2064 × 2752
iPad Pro M4 (clay) iPad 2064 × 2752

There is also a plain-English reference at /app-store-screenshot-sizes.

Deployment

Static output — any host that serves files will do. A production nginx server block with clean URLs, caching and security headers is in deploy/.

npm run build
rsync -avz --delete dist/ user@server:/var/www/appshot/

If you fork this for your own domain, change SITE_URL in src/lib/site.ts — canonicals, Open Graph tags, sitemap.xml and robots.txt all derive from it.

Tech stack

React 18 · TypeScript · Vite · Tailwind CSS · Canvas 2D

Runtime dependencies: react, react-dom, jszip, idb-keyval. That's the whole list — the router, the PNG encoder and the device frames are all in-repo, which keeps the bundle around 100 KB gzipped.

Roadmap

Contributions especially welcome on these:

  • Themed template packs — coordinated background, type and device treatment as one preset
  • Render exports in a Web Worker (large iPad batches currently block the main thread)
  • Filmstrip editing — see and edit all screens side by side
  • Localisation: one project, several languages, exported per locale
  • Import/export project as JSON, to carry work between machines without an account
  • Background image and gradient-mesh options

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md.

Adding a device is usually a one-line change in src/data/devices.ts, and a template is a small layout function in src/data/templates.ts. Both are good first contributions.

License

MIT © Encoder Bytes

Not affiliated with, endorsed by, or associated with Apple Inc. or Google LLC. "App Store" and "Google Play" are trademarks of their respective owners. Device frames are generic representations, not reproductions of any manufacturer's artwork.

About

No description, website, or topics provided.

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages