LLM Engineering
Single-File App Generation
Use when prompting an LLM to emit a complete, self-contained HTML app - all HTML, CSS, and JS in one file - that you will drop into a sandboxed iframe and run: an artifact, a preview pane, a generated micro-app, a code playground. Covers the output contract (one file, pinned CDN versions, module scripts, no build step), the iframe sandbox and CSP that make running untrusted output safe, and size caps. Also use when a generated file looks plausible and renders as a blank frame. If model output will execute in a browser, use this skill.
4 files
Description
Use when prompting an LLM to emit a complete, self-contained HTML app - all HTML, CSS, and JS in one file - that you will drop into a sandboxed iframe and run: an artifact, a preview pane, a generated micro-app, a code playground. Covers the output contract (one file, pinned CDN versions, module scripts, no build step), the iframe sandbox and CSP that make running untrusted output safe, and size caps. Also use when a generated file looks plausible and renders as a blank frame. If model output will execute in a browser, use this skill.
name: single-file-app-generation description: Use when prompting an LLM to emit a complete, self-contained HTML app (all HTML, CSS, and JS in one file) that you will drop into a sandboxed iframe and run - an artifact, a preview pane, a generated micro-app, a code playground. Teaches the output contract (one file, pinned CDN versions, module scripts, no build step), the iframe sandbox and CSP that make running untrusted output safe, size caps, and the failure modes that turn a plausible-looking file into a blank frame.
Single-File App Generation
A single-file app is a complete program - markup, styles, and scripts - in one
.html string you can write to an iframe and run with no build step. It is the
right unit whenever a model generates something a user should see run
immediately: an artifact, a live preview, a generated tool, a playground. The
skill is getting the model to emit output that actually runs, and running that
untrusted output without handing it your origin.
When to trigger
- You prompt an LLM for "an app / widget / visualization" and render its output live.
- Generated HTML renders as a blank frame, or works in a full tab but breaks in your embed.
- You need to run model-generated code in the browser without trusting it.
- You are building an artifacts pane, a preview iframe, or a code-playground feature.
The output contract
Tell the model exactly what to emit. Vague prompts produce multi-file projects,
bare npm install instructions, or React with no runtime. Require:
- One file, top to bottom. A single
<!DOCTYPE html>document with all CSS in a<style>and all JS in<script>tags. No external file references you do not control, no build step, no bundler, nonpm install. - Pinned CDN versions for any dependency. Every third-party import names an
exact version -
https://esm.sh/react@19.0.0, not@latestand not a barereact. Unpinned URLs are the top cause of an app that renders today and 500s next week when the CDN moves. Prefer an import map for readability. Seereference/output-contract.md. - ES module scripts for imports. Anything using
importmust be in<script type="module">; browsers reject bareimportin a classic script. Declare bare specifiers in an<script type="importmap">before the module. Seereference/output-contract.md. - Self-contained state and data. No network calls to APIs the frame cannot
reach; inline sample data or read from a documented
postMessagehandshake. - A visible failure path. Render an error into the DOM rather than only
console.error, so a broken app is diagnosable from the frame, not just the console.
Running it safely
Generated code is untrusted. Render it in a sandboxed iframe that CANNOT reach your origin:
- Use
sandbox="allow-scripts"and DO NOT addallow-same-origin. The two together let the framed script remove its ownsandboxattribute and escape - no safer than no sandbox at all. Withoutallow-same-originthe frame is an opaque origin: no cookies, nolocalStorage, no reading the parent. - Load the document via
srcdoc(or ablob:/data URL), never by writing it to a same-origin route. - Add a
Content-Security-Policy(a<meta http-equiv>inside the document, or the CSPsandboxdirective) as defense in depth on top of the attribute. - Cross-frame communication is
postMessageonly, and you validate every message.
See reference/sandbox-and-safety.md for the exact iframe wiring and CSP.
Core rules
- Cap the output size. Set a token/byte ceiling in the prompt and reject or
truncate oversize output before it hits the frame. See
reference/failure-modes.md. - Pin every dependency to an exact version. This is the single highest-value rule.
allow-scriptsyes,allow-same-originno. Non-negotiable for untrusted output.- Give the model a strict skeleton to fill, not a blank "write an app" prompt.
Reference files
reference/output-contract.md- the exact document skeleton, import maps vs script tags, pinning, the prompt template.reference/sandbox-and-safety.md- the iframe wiring, sandbox tokens, CSP, and the postMessage handshake.reference/failure-modes.md- blank-frame causes, size caps, and a triage checklist.
Added 2026-07-01. Back to the Skill Library.

Get Smarter About AI Dev
New tutorials, open-source projects, and deep dives on coding agents - delivered weekly.