skip to content

In fastlane, what does frame_screenshots (frameit) do after iOS or Android screenshots are captured?

level: middleimportance: should knowfreq 41%

answer

  1. it never launches the app
  2. images in, images out
  3. sits between capture and upload
  4. composites a device bezel around the shot

basics

~20 s

frame_screenshots, aliased frameit, is pure image post-processing: it reads the PNGs already produced by capture_ios_screenshots on iOS or capture_android_screenshots on Android and writes framed copies, each screenshot composited inside a device bezel with an optional background and title.

solid answer

~40 s

`frame_screenshots` — the canonical name behind `frameit` — runs *after* capture and *before* upload. Its input is a directory of images and its output is a directory of images: it composites each screenshot inside a picture of the device it was taken on, usually over a coloured background and often under a marketing title. It launches nothing, so unlike `capture_ios_screenshots` and `capture_android_screenshots` it does not care which platform produced the pixels; it cares only about image dimensions, because the bezel must match the device the shot came from. That is why it is a separate action rather than an option on either capture action: framing is an editing step you can re-run, skip, or apply to hand-made artwork.

go deeper

for a junior

Recall that framing is a separate optional step named frame_screenshots, aliased frameit, and that it edits images already captured rather than taking any screenshot itself.

for a middle

Explain the image-in, image-out model and why it lets one action serve screenshots from both capture_ios_screenshots and capture_android_screenshots despite their completely different capture mechanics.

for a senior

Show judgment about pipeline shape: framing kept restartable and separate so a cosmetic asset problem never blocks a release, and framing configuration maintained per platform because output dimensions differ.

for a principal

Own whether automated framing belongs in engineering at all. Weigh a marketing-owned artwork pipeline against a lane your team maintains, and decide who is accountable for listing copy at locale scale.

## What framing actually is `frame_screenshots`, aliased **`frameit`**, is a **post-processing step over image files**. It reads the PNGs a capture run produced and writes framed copies: the raw screenshot composited inside a picture of the hardware it was taken on, typically over a solid or gradient background, often with a short marketing title above the device. Crucially, it launches nothing. It never touches a simulator, an emulator, a physical device or your app. Its input is a directory of images and its output is a directory of images. That is the whole reason one action serves both platforms even though `capture_ios_screenshots` (XCUITest on simulators) and `capture_android_screenshots` (an instrumentation test APK on a device) produced those images in completely different ways. ## Where it sits in the pipeline 1. **Capture** — per platform, per device, per locale, into `output_directory`. 2. **Frame** — optional, over that directory, producing framed variants. 3. **Upload** — the platform's upload action reads the per-locale directories. Because step 2 is a separate action, you can iterate on the artwork without re-running step 1. Re-capturing a full locale matrix for a sailmaker measurement app costs simulator and device minutes; re-running the framing to change a background colour costs seconds. Folding framing into the capture actions would have thrown that away. ## What framing needs - **Device frame images** matching the hardware the screenshot came from. A bezel drawn for one device size composited around a screenshot from another produces obviously wrong artwork. - **A configuration describing the layout** — background, padding, where the device sits, where the title sits. In frameit this lives in a configuration file placed next to the images (conventionally `Framefile.json`), so different directories can be framed differently. - **Per-locale marketing copy**, when you use titles. A framed French screenshot of the sailmaker app's measurement sheet with an English headline above it is worse than an unframed one, so title text is kept per locale alongside the images rather than hard-coded. ## The platform angle Framing is where the two capture paths converge, and also where they diverge again: | | iOS | Android | |---|---|---| | source action | `capture_ios_screenshots` (`snapshot`) | `capture_android_screenshots` (`screengrab`) | | what produced the pixels | XCUITest on a simulator | instrumentation test APK on a device or emulator | | what the frame must match | the simulator model captured | the device or emulator resolution captured | | listing slots the output feeds | Apple display-size families | Google Play form-factor slots | The practical consequence is that a framed image is a **different size** from the raw screenshot, and each store's listing slots accept specific sizes. So framing is not free decoration — it is a decision about what dimensions you are producing, and a framing configuration that fits the Apple side does not automatically satisfy the Google Play side. Teams usually maintain framing configuration per platform for exactly this reason. ## When framing is worth it, and when to skip it - **Worth it** when the listing is a marketing surface and the screenshots are meant to sell a workflow rather than document a screen. A framed shot titled 'Measure a full mainsail in four taps' reads as a product page. - **Worth it** when you have many locales: framing is the only step that scales headline copy across a matrix as cheaply as capture scales the screenshots themselves. - **Skip it** when the listing slot expects raw device-sized screenshots, or when a design team supplies finished artwork separately. - **Skip it** when it becomes the only reason a capture run fails. Framing is cosmetic; a red lane that blocks a release because one bezel asset is missing has the priority backwards, so keep it a separate, restartable step. ## The mistakes that show up in interviews - Believing framing happens *during* capture and that the device draws its own bezel. It does not; a screenshot is the app's pixels only. - Believing the store frames images for you. Neither store does; whatever you upload is exactly what is displayed. - Believing framing is required. It is entirely optional, and plenty of shipped listings use raw captures. - Naming only `frameit` and never `frame_screenshots`, which signals familiarity with a blog post rather than with the action list. ## What a strong answer sounds like Name the canonical action, describe it as an image-in, image-out step between capture and upload, and explain why that separation is deliberate: it lets you re-run cheap editing without paying for capture again, and it lets one action serve two platforms whose capture mechanics have nothing in common.

  • Why is framing a separate action instead of an option on the two capture actions?
    Because it is editing, not capture. `frame_screenshots` takes images and returns images, so it can be re-run cheaply after a design change without paying for another XCUITest pass on simulators or another instrumentation run on Android hardware. Keeping it separate also lets one action serve both platforms, and lets you skip framing entirely without touching either capture lane.
  • What breaks if a framed screenshot is uploaded to the wrong listing slot?
    Framing changes the image's pixel dimensions, so a framed file no longer matches the raw device size it started as. Each store listing slot accepts specific sizes, so an upload can be refused for dimensions even though the artwork looks fine locally. Keep framing configuration per platform and check the output size before the upload lane runs.

saying these in an interview costs you the question

  • Thinks the device or simulator draws the bezel during capture
  • Believes the store adds device frames to uploaded images
  • Assumes framing is mandatory for a store listing
  • Cannot name frame_screenshots, only the frameit nickname
  • Ignores that framing changes the output image dimensions