The media section is the first thing people see on a JetBrains Marketplace plugin page. It's also where most plugins look their worst: full-screen IDE captures shrunk to carousel size, unreadable 13px text, desktop wallpaper around the window, and every screenshot a different size.
The good-looking ones are usually composed slides. A short headline sits on a tinted background next to a cropped, zoomed-in IDE window, and one thing on screen is highlighted. Making those by hand in a design tool takes a while, and you redo all of it whenever the UI changes.
So I built mpshots. It's a small Node CLI. You give it your raw IDE screenshots and a YAML file, and it renders a consistent set of Marketplace slides.
Raw window capture…
…and the slide mpshots makes from it.
What it does
You describe each slide in a shots.yaml:
output:
width: 1920
theme: dark
brand:
name: Air
accent: "#3574F0"
defaults:
uiScale: 2 # Retina capture
slides:
- id: accounts
layout: hero
headline: Bring your own agent and account
body: Switch between JetBrains AI, a ChatGPT account or your own API key
screenshot:
src: screenshots/accounts.png
crop: [574, 996, 1645, 720] # x, y, w, h in source pixels
highlight: [1561, 1256, 637, 413] # draws an accent outline with a glow
Then run mpshots build. You get one PNG per slide, plus an index.html that shows them at about the size the Marketplace carousel uses.
There are four layouts:
-
text-left: text on the left, IDE window on the right running off the edge of the slide. -
text-right: the mirror image oftext-left. -
hero: centred headline with a wide window below. -
window: the window on its own, no text.
On any slide you can add highlights, which outline something on screen. You can also add an overlay, a second window floating on top, such as a browser preview next to the IDE.
Every slide uses the same logical 1920×1080 canvas, and output.width sets the pixel size: 1920, 2560 or 3840. Your set always comes out with one aspect ratio, which the Marketplace guidelines ask for.
Here's the full set for the Air plugin, all from one spec:
The checks
Laying out slides wasn't the hard part. The hard part was knowing whether a slide will still be readable once it's shrunk into the carousel. Before rendering anything, mpshots validate checks:
-
IDE text size: it estimates how big the IDE's 13px UI font ends up after your crop and zoom (
13 × uiScale × zoom), and warns if it lands under 16px. - Upscaling: it warns if the screenshot has to be blown up more than 1.05×, because the result will look soft.
- Copy length: headlines over 60 characters, body text over 240.
- Hard errors: missing files, and crops or highlights that fall outside the image.
--strict turns warnings into failures, so you can run it in CI.
Building this taught me one thing: a 1920×1080 capture at 100% IDE zoom can't be both readable and sharp on a slide. To make the text big enough, you have to scale the capture up, and then it goes blurry. The fix is at capture time. Zoom the IDE to 125–150% (View › Appearance › Zoom IDE), or capture on a Retina display, and set uiScale to match. The Air screenshots above are 2800×1800 Retina window captures. They pass both checks without being scaled up.
Finding crop coordinates
Nobody wants to guess pixel rectangles. mpshots grid draws a labelled pixel grid over a capture so you can read off [x, y, w, h] directly:
mpshots grid screenshots/accounts.png
# → screenshots/accounts.grid.png
How it renders
There's no headless browser. Layout is done by satori, which turns flexbox-style elements into SVG. resvg turns that SVG into pixels, and sharp handles crops and resampling. Each screenshot is resampled once, with Lanczos, straight to the final output size. A slide takes about two to three seconds. It runs anywhere Node 18 does, CI included.
Try it
It installs straight from GitHub:
npm i -g github:jreznot/mpshots#v0.1.0
mpshots init # creates shots.yaml and screenshots/
mpshots build
The repo includes two complete examples: a set built from generated mock IDE screens, and the Air set above from real captures. Clone it and run mpshots build in examples/air to see the whole pipeline.
Next I'd like to remove the manual capture step. An IDE action could save a clean window capture at a known zoom and write the crop rectangles for you.
Issues and PRs are welcome: github.com/jreznot/mpshots.






Top comments (0)