create-chatgpt-mockup
Render pixel-accurate ChatGPT mobile (iOS) screen mockups in light mode from a thread JSON. Supports user text bubbles, user image attachments, assistant markdown prose, citation chips, the OpenAI spiral logo, the Apps-SDK GPT chip in the composer, and three header styles (model-tag, plain title, "G…
Install / Use
npx skills add gooseworks-ai/goose-skills --skill create-chatgpt-mockupInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
AI & Machine LearningSupported Platforms
Our assessment of create-chatgpt-mockup
create-chatgpt-mockup scores 93/100 on our quality scale, 243rd of 952 AI & Machine Learning skills we index (top 26%).
Its SKILL.md is 15 KB long, well organised into 16 sections with 4 code examples: a thorough specification that gives an agent plenty to work with.
With 1,222 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated 33 days ago, so create-chatgpt-mockup is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Safety scan
No issues foundOur scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands.
Automated pattern scan on 2026-10-26. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.
create-chatgpt-mockup compared with similar skills
All 4 of these similar skills score higher than create-chatgpt-mockup; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| create-chatgpt-mockup (this skill)by gooseworks-ai | 93 | 1.2k | 33d ago | SKILL.md |
| claude-memby thedotmack | 100 | 103.1k | today | CLAUDE.md |
| taste-skillby Leonxlnx | 100 | 102.4k | today | CLAUDE.md |
| Understand-Anythingby Egonex-AI | 100 | 88.2k | 3d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 77.8k | 1d ago | CLAUDE.md |
Frequently asked questions
- How do I install create-chatgpt-mockup?
- Run
npx skills add gooseworks-ai/goose-skills --skill create-chatgpt-mockup. The install tabs above show the steps for each supported agent. - Which AI agents does create-chatgpt-mockup work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is create-chatgpt-mockup safe to use?
- Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is create-chatgpt-mockup still maintained?
- The repository was last updated 33 days ago, so create-chatgpt-mockup is actively maintained.
Skill content
View source on GitHubname: create-chatgpt-mockup description: Render pixel-accurate ChatGPT mobile (iOS) screen mockups in light mode from a thread JSON. Supports user text bubbles, user image attachments, assistant markdown prose, citation chips, the OpenAI spiral logo, the Apps-SDK GPT chip in the composer, and three header styles (model-tag, plain title, "Get Plus"). Fixed 9:16 viewport. 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-chatgpt-mockup
Purpose
Generate single-frame ChatGPT mobile screens that read as real iOS captures — accurate header chrome, user/assistant message styling, composer pill, status bar, and the OpenAI spiral mark. Designed for use inside ad creatives, social posts, video storyboards, and product mockups.
If you need an animated, video-recorded chat reveal (bubbles popping over time, SFX, music bed, end card), use the render-chatgpt-chat skill. This atom only produces a single still frame.
Inputs
Compose a thread.json matching the schema below, then pass it to render.js.
Thread JSON schema
{
"statusBar": {
"time": "9:41",
"dnd": false
},
"header": {
"style": "model-tag",
"title": "ChatGPT",
"model": "5.1",
"rightIcons": ["personPlus", "dottedCircle"]
},
"messages": [
{ "type": "user-image", "src": "assets/photo.jpg", "aspect": "square" },
{ "type": "user-text", "text": "Make this face sunscreen better" },
{
"type": "assistant",
"title": "Optional H1 with spiral logo",
"feedback": true,
"text": "Markdown-ish prose. **bold**, *italic*, ## H2, * bullet, 1. ordered, [[cite:Source +1]], [[icon:💡]] inline-icon."
}
],
"composer": {
"placeholder": "Ask anything",
"text": "Typed text to show with caret",
"cursor": true,
"streaming": false,
"chip": { "name": "Seatfinch" }
}
}
Field reference
statusBar
time— string shown top-left (e.g."9:41","08:18").dnd— whentrue, renders a small moon glyph next to the time (matches iOS Focus-on indicator).
header.style — one of:
"model-tag"—≡ ChatGPT 5.1 ▾ ●●— used when a specific model is active."title-only"—≡ ChatGPT › ●●— the plain in-chat header."plain-title"—≡ Get Plus ✦ ●●— for the upsell/empty-state title.
header.rightIcons — array of icon keys, rendered left-to-right on the right side. Available: "personPlus", "dottedCircle", "edit", "more". Default is ["personPlus", "dottedCircle"] for model-tag, ["edit"] for title-only.
messages[] — one of:
{ "type": "user-image", "src": <path>, "aspect": "square"? }— relativesrcpaths resolve against the thread.json directory.{ "type": "user-text", "text": <string> }— right-aligned soft-gray bubble.{ "type": "assistant", "text": <markdown>, "title"?: <string>, "feedback"?: <bool> }— left-aligned plain prose. Iftitleis set, an OpenAI spiral logo + bold title is rendered above the body.feedback: falsehides the thumbs-up/down chips.
Assistant text markdown — supported syntax:
**bold**,*italic*# H1,## H2,### H3* item/- itembullet lists1. itemordered lists---horizontal rule[[cite:Some Source +1]]— pill citation chip[[icon:💡]]— inline emoji prefix (kept un-escaped)- Single
\n→ soft line break (<br>); double\n\n→ new paragraph
composer
placeholder— shown whentextis empty (default"Ask anything").text— typed-in text. When present, the send button activates (black bg).cursor— whether to render the blinking caret aftertext(defaulttrue).streaming— whentrue, replaces the send arrow with a stop square (matches "response generating" state).chip— optional GPT chip in the composer.chip.nameis the GPT name. Setsplaceholderto"Ask ChatGPT"if you don't override it.
CLI
node render.js --thread examples/01-sunscreen-image.json
node render.js --thread my-thread.json --output ./exports --name nightly
Flags
| Flag | Effect |
|---|---|
| --thread <path> | (required) JSON file matching the schema above |
| --output <dir> | parent dir for the dated output folder; default ./chatgpt-mockup-exports/ |
| --name <slug> | override the output folder slug |
Output
<output>/<YYYY-MM-DD>-<slug>/
index.html # standalone HTML (CSS inlined)
screenshot.png # 2250 × 4002 PNG (DPR 3, 9:16)
thread.json # copy of the input for reproducibility
Workflow
- Receive a brief or existing thread JSON.
- If only a brief is given, compose
thread.jsonmatching the schema above. - Run
node render.js --thread <path>. - Open the PNG. If anything looks off (header alignment, bubble width, missing icon), edit the JSON or
templates/chat.cssand re-render.
Setup (one-time)
cd create-chatgpt-mockup
npm install
npx playwright install chromium
Quality checks
- [ ] Renders in light mode only (white background, dark text). Dark-mode rendering is out of scope for v1.
- [ ] Status bar time and right cluster (signal / wifi / battery) sit at the very top, no clipping under the iOS status-bar safe area.
- [ ] Header chrome icons (hamburger / personPlus / dottedCircle / edit / more) all visually weigh the same as a real ChatGPT iOS screenshot at the same display size — eyeball, don't pixel-match. Sub-reading-weight icons read as broken even when their pixel dimensions "match the spec."
- [ ] Header model tag (
5.1,5.2) sits inline withChatGPTand its chevron — no wrapping. - [ ] User bubble is right-aligned, soft-gray (
#F4F4F4),border-radius: 28px, max-width 78% of stage. - [ ] User image attachments use the same
28pxcorner radius and sit right-aligned above the text bubble. - [ ] Assistant body is plain prose (no bubble), left-aligned, full-width within the gutter.
- [ ] Composer corner radius is 999px (full pill),
1pxborder#E5E5E5, send button is44 × 44round. - [ ] When
composer.textis set: send button is solid black with a white up-arrow. Caret sits right after the last character of typed text. - [ ] When
composer.streaming: true: send button shows a black square stop icon. - [ ] When a citation marker
[[cite:Foo +1]]is in the assistant text, it renders as a pill chip inline at the end of the sentence.
Failure modes
| Symptom | Cause | Fix |
|---|---|---|
| Thread file not found | Wrong path or running from a different cwd | Use absolute paths or run from the skill directory |
| Image attachment shows broken-image glyph | src is relative but the renderer couldn't resolve it | render.js resolves relative src against the thread.json's directory — make sure the asset exists at that path |
| Send button stays light gray after typing | composer.text is empty string "" instead of unset | Either omit text entirely or set it to a real string |
| Caret renders as a stray \| separated from the text | Caret span is being treated as a flex child | The CSS rule for .composer .input uses inline content flow — do not switch it to display: flex |
| Streamed list-item words render with no spaces ("Howconversationswork") | .word { display: inline-block } collapses inter-span text-node whitespace inside <div> parents (works fine inside <p>) | Use display: inline for .word — modern browsers honor filter: blur() + opacity transitions on inline elements too |
| Bullets visible while list-item text is still hidden during streaming | CSS list-style markers are browser-painted; the word-stream wrapper only sees text nodes | The atom auto-converts <ul><li>X</li></ul> to <div class="md-list"><div class="md-li">• X</div></div> when stream: true — keep that pass; don't regress it. Any new markdown that emits browser-painted glyphs (::marker, quotes, counter-content) needs the same text-conversion treatment. |
| Markdown --- doesn't render an <hr> | The --- line isn't on a line by itself, or the surrounding text didn't end its paragraph | Surround --- with blank lines on both sides |
| Stanzas of a poem joined into single paragraphs | Lines separated by single \n get joined as a single paragraph but with <br> between them — this is the intended behavior. If you want stanza breaks, use \n\n between stanzas. |
| Header right cluster overlaps the model tag on long titles | Title text is too wide for the centered slot | Shorten header.title, drop the model tag, or switch header.style to "title-only" |
Files
| File | Purpose |
|---|---|
| render.js | CLI entry — parses flags, generates HTML, takes screenshot, writes outputs |
| generate.js | Thread JSON → standalone HTML page (markdown-ish parser inside) |
| screenshot.js | HTML → PNG via Playwright (chromium headless) at fixed 750×1334 / DPR 3 |
| templates/chat.css | All visual styling |
| templates/icons.js | Inline SVG icons (hamburger, chevrons, spiral logo, mic, plus, send arrow, stop square, signal/wifi/battery, thumbs up/down) |
| examples/*.json | 6 reference threads exercising every variant |
| examples/assets/ | Placeholder image assets used by image examples |
| tests/run-all.sh | Builders only, in the goose-skills repo (installs have no tests/): render every example into tests/output/ for visual review |
Known limitations
- Light mode only. Dark mode would require a separate theme block and is out of scope for v1.
- No carousel / horizontal-scroll cards. The Apps-SDK ticketing-app reference shows a horizontal card carousel inside the assistant response; not modeled here.
- No live keyboard rendering. The composer is the bottom pill only — no on-screen keyboard chrome, suggestion bar, or QWERTY grid. (If you need the keyboard, scale the screen down 50% and overlay a separate keyboard image.)
- Markdown is intentionally minimal — no tables, no fenced code blocks with syntax highlighting, no nested lists. Add to
generate.js#renderMarkdownif a brief requires more. - Emoji rendering depends on system fonts. Chromium on macOS ships Apple Color Emoji; on Linux ships Noto Color Emoji.
Quality Checks
Render each examples/*.json with render.js and open the PNGs (builders in the goose-skills repo can run bash tests/run-all.sh, which renders all six into tests/output/), then confirm:
- Every example renders without error. All six
examples/*.jsonproduce anindex.html+screenshot.png+thread.jsontriplet;render.jsexits0. - Dimensions are stable. Each
screenshot.pngis 2250 × 4872 (the.stageis750 × 1624andscreenshot.jscaptures atdeviceScaleFactor: 3). A wrong size means the stage box or DPR changed. - Light mode, white background. Background is white, text near-black. This atom does not render dark mode.
- Status bar. Time sits top-left; the signal / wifi / battery cluster sits top-right, unclipped. When
statusBar.dnd: true(see02-sleep-apnea-long.json,05-seatfinch-gpt-chip.json) a moon glyph renders next to the time. - Header style matches the JSON.
model-tagshowsChatGPT 5.1 ▾(01-sunscreen-image.json,06-short-howto.json);title-onlyshows the plain title + right chevron (02,03,05);plain-titleshows the upsell title with no chevron (04-empty-typing.json). The center cluster never wraps and the right icons never overlap it. - User turns. User text is a right-aligned soft-gray bubble (
#F4F4F4,28pxradius). Auser-image(see
Truncated for display — read the full file on GitHub.
Related Skills
claude-mem
103.1kPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode + More
taste-skill
102.4kAgent skills that give coding agents taste: art direction, reference images and a browser check instead of generic AI pages
Understand-Anything
88.2kGraphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.
headroom
77.8kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
