fastlane frameit: Add Device Frames and Titles to Screenshots
How to use fastlane frameit: add device frames, titles and backgrounds with Framefile.json and .strings files, plus its limits and when to use another tool.
ScreenShipper team · · 7 min read
TL;DR: frameit is the fastlane action that wraps screenshots in device frames. Running fastlane frameit frames every screenshot in the current folder and its subfolders, downloading the frame images on first run. Framed images on their own can't be uploaded to the App Store, so for store-ready output add a Framefile.json with a background and titles, plus title.strings and keyword.strings for each language.
How frameit Works
frameit looks at each screenshot, works out which device it came from based on its resolution, and composites the matching device frame around it. The frames originally came from Facebook's device frameset and are now kept in a fastlane repository; the documentation lists support for iPhone, iPad and Mac, plus a set of Android devices. frameit uses ImageMagick for the image processing, so install it first on macOS with brew install imagemagick.
The main commands:
| Command | What it does |
|---|---|
fastlane frameit | Frames iOS and macOS screenshots in the current folder and subfolders |
fastlane frameit silver | Uses silver device frames instead of the default color |
fastlane frameit android | Frames Android screenshots |
fastlane frameit download_frames | Downloads the latest frame images |
frameit writes a framed copy next to each original, with _framed added to the file name, so your raw captures stay untouched. Inside a Fastfile, use the frame_screenshots action (alias frameit). It accepts frame colors as booleans, such as frame_screenshots(white: true), along with path, use_platform, force_device_type, and resume, which only reframes screenshots that are newer than their framed file.
Why You Need a Framefile.json for the App Store
Run frameit with no configuration and you get a device frame around your screen at full resolution. The image is now larger than any accepted screenshot size, and fastlane's documentation states plainly that these can't be uploaded to the App Store directly. They're meant for websites, print and email.
To produce store-ready images, fastlane's screenshot guide says you have to provide a Framefile.json with titles and a background. frameit then renders a canvas at the original screenshot size, places a scaled-down framed device on it, and adds your text. The result matches the dimensions App Store Connect expects.
A background is also a prerequisite for text: the documentation notes that without a background, titles aren't added at all.
Writing a Framefile.json
Put Framefile.json in your screenshots folder, next to the language folders that snapshot creates. It has three top-level keys:
device_frame_version, usually"latest"default, settings for every screenshotdata, a list of per-screenshot overrides, each matched by afilter
A minimal file contains "device_frame_version": "latest", a default object such as { "background": "./background.jpg", "padding": 50, "title": { "color": "#1D1D1F" } }, and a data list such as [ { "filter": "01Home", "keyword": { "color": "#FF6B00" } } ]. The filter value matches part of the screenshot's file name, so 01Home targets every screenshot whose name contains it, in every language and on every device.
Keys you can set under default:
| Key | Default | What it controls |
|---|---|---|
background | none, required | Background image behind the device |
title, keyword | none | Text styling: color, font, font_size, font_weight |
padding | 50 | Space around the device, in pixels, "30x60" or percentages like "5%x10%" |
stack_title | false | Puts the keyword above the title instead of on one line |
title_below_image | false | Moves the text below the device |
show_complete_frame | false | Shrinks the device so the whole frame is visible instead of running off the bottom |
interline_spacing | 0 | Line spacing for multi-line titles |
font_scale_factor | 0.1 | Text size relative to the image when no font_size is set |
frame | default color | BLACK, WHITE, GOLD or ROSE_GOLD |
title_min_height | none | Reserves a minimum height for the title area |
use_platform, force_device_type | auto | Override device detection, for example ANDROID |
Entries under data can override keyword, title, frame, use_platform and force_device_type for screenshots that match their filter. For Mac screenshots, frameit also supports an offset setting to position the window precisely.
Titles and Keywords in Every Language
The text itself doesn't live in Framefile.json. It comes from two files in each language folder:
title.strings, the main caption for each screenshotkeyword.strings, a short highlighted word or phrase shown with the title in its own color or font
Entries use the filter as the key, for example "01Home" = "Plan meals in seconds"; in en-US/title.strings and the German version in de-DE/title.strings. Because the key is the same in every folder, one Framefile.json drives all languages.
Two formatting rules trip people up, both stated in the documentation:
- The .strings files must be UTF-8 or UTF-16 (big-endian with a byte order mark).
- Each file must begin with an empty line.
If titles silently fail to appear, check those two rules first, then confirm that a background is set and that the filter actually matches the file names. Then review every language by eye. Long German or French titles may wrap onto extra lines, and right-to-left languages need a careful look. Our localization guide covers what to check.
Limitations of frameit
frameit is reliable for a consistent, simple look across many languages. Its limits show up when marketing wants more:
| Limitation | What it means |
|---|---|
| Fixed layout | One device per screenshot with text above or below; no panoramas, multiple devices or tilted 3D poses |
| Detection by resolution | Unusual screenshot sizes may not match a frame; you may need force_device_type |
| Frame catalog | The newest devices depend on the frames repository being updated; legacy options such as use_legacy_iphonex exist for older looks |
| Text rendering | Fonts and edges depend on ImageMagick; the docs suggest reinstalling it if you see artifacts around text |
| No overflow warnings | Long translations aren't flagged automatically |
Before uploading, also check the output files themselves. Confirm the dimensions and that there's no alpha channel, since Google Play rejects PNGs with transparency. On a Mac, sips -g pixelWidth -g pixelHeight -g hasAlpha file.png shows all three, or use the free screenshot size checker. For Google Play, remember that the long side of a screenshot can be at most twice the short side.
frameit in a Complete fastlane Lane
frameit is usually the middle step of a screenshot lane. fastlane's iOS guide shows a lane named screenshots that calls capture_screenshots, then frame_screenshots(white: true), then upload_to_app_store. Run it with fastlane screenshots and the whole pipeline repeats in minutes whenever your UI changes.
For Android, capture with capture_android_screenshots, frame with frame_screenshots(use_platform: "ANDROID") or the fastlane frameit android command, and upload with upload_to_play_store. Our guides to fastlane snapshot and fastlane screengrab cover the capture side.
Alternatives to frameit
Choose frameit when you need a repeatable pipeline in CI, a simple framed look is enough, and your team is happy editing JSON and .strings files.
Consider a design tool or a dedicated generator when:
- The first screenshot needs a custom hero layout, illustration or social proof
- You want panoramic backgrounds that flow across screenshots
- Non-developers on the team need to edit headlines and colors
- You want to see overflow warnings for every language before export
A common hybrid is to keep fastlane snapshot or screengrab for capturing raw screens and do the design step elsewhere. Our guides to screenshot mockups and choosing a screenshot generator explain the trade-offs.
Frequently Asked Questions
Why can't I upload frameit screenshots to App Store Connect?
Without a Framefile.json background and titles, frameit outputs the device frame at full resolution, which no longer matches any accepted screenshot size. Add a Framefile.json with a background and titles so the output keeps the original dimensions.
How do I change the frame color in frameit?
Use fastlane frameit silver, pass a color such as white: true or gold: true to frame_screenshots, or set the frame key in Framefile.json to BLACK, WHITE, GOLD or ROSE_GOLD.
Does frameit work with Android screenshots?
Yes. Run fastlane frameit android, or set use_platform to ANDROID in Framefile.json or the action. The Android frame set is smaller than the iOS one.
Why are my frameit titles missing?
Check four things: a background is set, the .strings files are UTF-8 or UTF-16 BE with a byte order mark, each file starts with an empty line, and the filter key matches part of the screenshot file name.
Sources
From raw captures to store-ready screenshots
Drop your simulator or emulator captures into a template and export every store size, or frame a single screen with the free mockup generator.