Every app update means regenerating screenshots at exact pixel dimensions for multiple devices. It's tedious, error-prone, and eats up time better spent building. This tutorial walks through appshots, an open-source CLI that handles framing, capture, and validation in one command.
The Solution: appshots
appshots is an MIT-licensed CLI and Node.js library that turns raw screenshots into store-ready images. It ships with 26 device presets covering iPhone, iPad, Android, Mac, Apple Watch, Apple TV, and Vision Pro.
Install globally or run with npx:
npm install -g appshots
# or just use npx — no install needed
Quick Start
Three commands cover the full workflow:
# 1. Frame existing screenshots
npx appshots frame ./screenshots \
--device iphone-6.9 \
--background "linear-gradient(135deg, #667eea, #764ba2)" \
--title "Your App"
# 2. Capture from a running app
npx appshots capture --url http://localhost:3000 \
--device iphone-6.9 --path / /features
# 3. Validate before uploading
npx appshots validate ./screenshots
Frame Your Screenshots
The frame command wraps existing images in a styled container. No browser required.
npx appshots frame ./raw-screenshots \
--device iphone-6.9 \
--background "linear-gradient(135deg, #667eea, #764ba2)" \
--title "Track What Matters" \
--subtitle "AI-powered insights, instantly"
Key options:
| Option | Default | Notes |
|---|---|---|
--device |
iphone-6.9 |
Any of the 26 presets |
--background |
#000000 |
Solid hex or CSS gradient |
--title |
— | Bold overlay text |
--subtitle |
— | Secondary text |
--padding |
0.08 |
Ratio 0-0.4 |
--border-radius |
0.04 |
Ratio 0-0.2 |
--no-shadow |
— | Disables drop shadow |
Device Presets
Run npx appshots devices to see all 26. The most common:
| Preset | Dimensions | Target |
|---|---|---|
iphone-6.9 |
1320 x 2868 | iPhone 16 Pro Max, Air |
iphone-6.3 |
1206 x 2622 | iPhone 17 Pro, 17 |
ipad-13 |
2064 x 2752 | iPad Pro M4/M5, Air M3 |
android-phone-tall |
1080 x 2400 | Modern Android (20:9) |
mac |
2880 x 1800 | MacBook Pro |
Config File
For repeatable workflows, generate a config:
npx appshots init
This creates appshots.config.ts:
import { defineConfig } from 'appshots';
export default defineConfig({
devices: ['iphone-6.9', 'ipad-13'],
frame: {
background: 'linear-gradient(135deg, #667eea, #764ba2)',
padding: 0.08,
shadow: true,
},
capture: {
baseUrl: 'http://localhost:3000',
screens: [
{ name: 'home', path: '/', title: 'Track What Matters' },
{ name: 'features', path: '/features', title: 'AI Insights' },
],
},
output: './store-screenshots',
});
The capture command needs Playwright: npm i -D playwright
Validate Before You Upload
npx appshots validate ./store-screenshots
# ✓ home.png 1320x2868 (iPhone 6.9")
# ✗ old-screen.png 1080x1920 → PNG has transparency.
Checks dimensions, format, transparency, file size, and color space.
Programmatic API
import { frameScreenshot, validateScreenshots } from 'appshots';
const buffer = await frameScreenshot({
input: './home.png',
device: 'iphone-6.9',
title: 'Welcome',
options: { background: '#1a1a2e' },
});
Links
Issues, PRs, and new device presets welcome.


Top comments (0)