Skip to content
Marketing
Skill

/create-imessage-mockup

Render pixel-accurate iMessage screenshot mockups (DM or group) from a thread JSON. Supports minimal, with-keyboard, and full iPhone 15 Pro frame variants. Outputs HTML + PNG.

From plugin
goose-skills
1.3k181 skills

Claude Code

$ npx -y skills add gooseworks-ai/goose-skills --skill create-imessage-mockup --agent claude-code

SKILL.md

create-imessage-mockup.SKILL.md
name: create-imessage-mockup
description: Render pixel-accurate iMessage screenshot mockups (DM or group) from a thread JSON. Supports minimal, with-keyboard, and full iPhone 15 Pro frame variants. Outputs HTML + PNG.
status: superseded
superseded_by: phone-chat@1.2.0

> **Superseded:** the video kit now does this with the phone-chat part, version 1.2.0, in the parts folder of this repository. Every phone-chat style is a style file that draws the same screen frame by frame from the plan's scenes, with the original sounds, in the kit's browser. This atom stays, unchanged in behaviour, for skills outside the kit until they move; its scripts still run.

create-imessage-mockup

Generate iMessage screenshots that look like real iOS captures — correct bubbles with tails, typing indicators, timestamps, "Delivered" captions, group avatars + sender names, keyboard chrome, and an optional iPhone 15 Pro bezel with Dynamic Island and status bar.

Purpose

Turn a structured thread JSON into a believable iMessage screenshot — first as standalone HTML (`generate.js` + `templates/chat.css`), then rasterized to PNG with headless Chromium (`screenshot.js`/`render.js` via Playwright). It is the atom you reach for when an ad, social post, or video scene needs a fake-but-convincing iOS message capture.

What it gets right, grounded in the renderer:

  • **Bubble runs and tails** — blue `sent` bubbles (right) and gray `received` bubbles (left), with a curved tear-drop tail drawn only on the *last* bubble of each consecutive sender run (`isLastOfRun` in `generate.js`).
  • **Dark-themed iOS chrome** — `theme: "dark"` flips the page to the iOS dark conversation look; the status bar, Dynamic Island, and keyboard match iPhone 15 Pro.
  • **Group affordances** — group threads (`mode: "group"`) add per-sender colored avatar circles, sender names above the first bubble of a run, and a 4-tile group-header badge.
  • **Beats for storyboards** — `timestamp` pills, a static-but-mid-animation `typing` three-dot bubble, `attachment` cards, and "Delivered"/"Read" captions let you stage individual frames of a conversation.
  • **Three crops** — `--minimal` (bubbles only), `--with-keyboard` (header + iOS keyboard), and `--with-iphone-frame` (full bezel + Dynamic Island + status bar over a gradient backdrop).

The atom embeds **no LLM** — it is deterministic. The orchestrating agent is responsible for composing the thread JSON; the renderer only draws exactly what the JSON says.

When to use

  • Need a fake iMessage screenshot for an ad, social post, video scene, or product mockup.
  • Want a side-by-side hero image showing a conversation in an iPhone frame.
  • Need a typing indicator or "Delivered" beat for a video storyboard.

If you're rendering programmatic graphic frames more broadly (cards, posters, infographics), use the `goose-graphics` skill instead.

Inputs

The skill is deterministic — it does not embed an LLM. To translate a free-form prompt into a thread, the orchestrating agent (you) composes a JSON file matching the schema below, then invokes the renderer.

Thread JSON schema

{
  "mode": "dm" | "group",
  "title": "Karaoke Crew",
  "participants": [
    { "id": "me",    "name": "Me",    "self": true },
    { "id": "sarah", "name": "Sarah", "color": "#FF9500", "initials": "S" }
  ],
  "messages": [
    { "type": "timestamp", "label": "iMessage\nToday 9:41 AM" },
    { "type": "timestamp", "bold": "Sat, Jan 2", "light": "11:07" },
    { "type": "text",      "from": "sarah", "text": "Did we crash it?" },
    { "type": "text",      "from": "me",    "text": "Couldn't withstand our friendship", "delivered": true, "read": false },
    { "type": "typing",    "from": "sarah" }
  ],
  "keyboard": { "leftIcon": "plus" }
}
  • `mode` — `dm` or `group`. If omitted, auto-detected from the participant count.
  • `participants[].self: true` marks the user (sent bubbles, no avatar).
  • `participants[].color` is the avatar background; defaults from a 6-color palette.
  • `participants[].initials` defaults to the first letter of `name`.
  • `messages[]`:
  • `timestamp` — centered pill. Use `label` (newline-separated bold/light) or explicit `bold` and `light` fields.
  • `text` — text bubble. `delivered: true` on the last sent bubble in a run renders the "Delivered" caption (or "Read" if `read: true`).
  • `typing` — animated three-dot bubble (rendered as a static mid-animation frame for screenshot determinism).
  • `keyboard.leftIcon` — `"plus"` (default) or `"camera"`.

CLI

node render.js --thread examples/group-with-frame.json --with-iphone-frame
node render.js --thread examples/dm-with-keyboard.json --with-keyboard
node render.js --thread examples/dm-minimal.json       --minimal
node render.js --thread my-thread.json --with-keyboard --output ./my-exports/ --name nightout

Flags

| Flag | Effect | |---|---| | `--thread <path>` | (required) JSON file matching the schema above | | `--prompt "<brief>"` | prints the schema and exits — agent must compose a thread.json and re-invoke | | `--minimal` | bubbles + timestamps only (no header, no keyboard, no frame) | | `--with-keyboard` | bubbles + iOS keyboard chrome (default) | | `--with-iphone-frame` | full iPhone 15 Pro bezel + Dynamic Island + status bar + soft gradient backdrop | | `--dm` / `--group` | force chat mode (otherwise auto-detected from participants) | | `--name <slug>` | override the output folder slug | | `--output <dir>` | parent dir for the dated output folder; default `./imessage-mockup-exports/` |

Frame flags are mutually exclusive.

Output

<output>/<YYYY-MM-DD>-<slug>/
  index.html       # full standalone HTML
  screenshot.png   # rendered PNG (DPR 3, "Retina")
  thread.json      # copy of the input for reproducibility

Default `<output>` is `./imessage-mockup-exports/` in the cwd.

Workflow

1. Receive a prompt or existing thread JSON. 2. If only a prompt was given: compose a thread.json matching the schema, save it

Read more
@gooseworks-ai
Ships withgoose-skills

Put your AI agent on the growth team. Research customers and competitors, analyze what is working, create the next campaign, and learn from the result.

1.3k181 skills
Get the whole plugin

Stars on GitHub

Momentum

stars in total
1.3k
Star history of gooseworks-ai/goose-skills on GitHub, a chart by star-history.com

Other skills on goose-skills.

goose-ads

goose-ads

Edit, resize, animate and study image ads with GooseWorks in this chat. New static or image ads go to the make-static-ads skill…

goose-video

goose-video

Make a video ad in this chat from a real reference ad, found or theirs; styles are the fallback. Follow every answer's next_step.

gooseworks

gooseworks

GooseWorks growth coworker and router for markets, competitors, audiences, creators, campaigns, ads, photos, graphics, video,…

More skills from other plugins.

seo

seo

Comprehensive SEO analysis for any website or business type. Full site audits, single-page analysis, technical SEO (crawlability,…

@agricidaniel@agricidanielInstall Skill
brag

brag

Turn the current project website into a short, polished, shareable launch video using Hyperframes. Use when someone says "/brag",…

brag2w21k
@latent-spaces@latent-spacesInstall Skill
geo-audit

geo-audit

Full website GEO+SEO audit with parallel subagent delegation. Orchestrates a comprehensive Generative Engine Optimization audit…

Questions about create-imessage-mockup.

Which coding agents can use create-imessage-mockup?
create-imessage-mockup installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.