Simon Willison's One-Prompt Web Component Is a Vibe-Coding Security Lesson
A GPT-5.5-generated Web Component that fetches and renders raw GitHub file content client-side is a small, telling example of how little scrutiny 'vibe-coded' front-end code gets before it ships.
Key Takeaways
- Simon Willison built a working `<github-code>` Web Component that fetches and displays GitHub file snippets from a single natural-language prompt to GPT-5.5, publishing both the prompt and a live demo.
- Its core mechanic — fetch a remote file client-side and render its text into the DOM — is a shape that has produced real DOM-based XSS bugs elsewhere when fetched content isn't escaped before insertion.
- Willison's transparency in publishing the exact prompt is good practice, but it doesn't substitute for the review any client-side fetch-and-render component should get before wider reuse.
- The broader lesson: single-prompt LLM-generated components are now trivial to produce and publish, which raises the stakes on treating AI-authored front-end code as code, not as a demo.
A code embed built in one prompt
Simon Willison, the developer behind Datasette and a widely read commentator on applied LLM use, published an experimental Web Component on 7 July 2026 that lets a page embed a slice of code straight from GitHub. Point <github-code href="..."> at a GitHub blob URL with a line range — for example, lines 9 through 18 of a file in his sqlite-ast repository — and the component renders those lines with line numbers. He built it from a single prompt to GPT-5.5 ("let's build a Web Component for embedding code from GitHub") and published both the prompt and a live version of the tool.
What the component actually does
Under the hood it's a simple pipeline: parse the GitHub blob URL and line-range fragment, rewrite it to the equivalent raw.githubusercontent.com URL, fetch() that URL client-side, then slice out and display the requested lines. Willison notes it currently has no syntax highlighting — a first pass, not a polished library.
Why the shape of this component matters
Strip away the GitHub branding and this is an instance of a very common — and very commonly mishandled — pattern: fetch text from a third-party source in the browser, then insert it into the DOM. Source files are attacker-influenceable in the general case, since anyone can put arbitrary content, including HTML- or script-like strings inside a comment or string literal, into a public GitHub file. How that fetched text reaches the page therefore matters. Insert it via textContent or an equivalent escaping path and it stays inert; insert it via innerHTML without escaping, and a crafted line of "code" can execute as markup in the embedding page. Nothing in Willison's post confirms which path this specific component takes — and that's the point. It's exactly the kind of implementation detail a one-prompt build can get right or wrong without anyone noticing until the component is reused somewhere with a wider blast radius.
Vibe-coded components entering real toolchains
This is a useful, low-stakes case study of a pattern we see in client engagements: teams increasingly ship small front-end components authored end-to-end by an LLM from a short prompt, sometimes with genuine transparency — as Willison does, publishing the exact prompt used — but without the review a hand-written equivalent would get. That's a reasonable trade-off for a personal blog demo. It's a different calculus for a component that ends up embedded in a product, an internal tool, or anything that renders content pulled from outside your trust boundary. Any component that fetches remote content and writes it into the page, AI-generated or hand-rolled, belongs in the same review path: check the rendering sink, check whether the source is genuinely trusted, and don't assume "it's just code from GitHub" means the content is safe to treat as markup.
Frequently Asked Questions
Is Simon Willison's github-code Web Component known to be vulnerable to XSS?
No vulnerability has been reported or demonstrated. The post doesn't specify whether fetched content is inserted via an escaping-safe method like `textContent` or a riskier one like `innerHTML`; the point is that this fetch-and-render shape is one where that implementation detail decides whether the component is safe.
What is 'vibe coding' and why does it matter for security?
Vibe coding means producing working software from natural-language prompts to an LLM with minimal manual code review. It matters for security because components built this way can reach production or public reuse without the scrutiny a hand-written equivalent handling remote or untrusted content would normally get.
What's the safe way to render fetched remote text in a Web Component?
Use a DOM API that treats the content as text, not markup — such as setting `textContent` or building text nodes — rather than `innerHTML`, unless the content has been explicitly sanitized. This holds regardless of whether the code was written by a person or generated by an LLM.
Sources
- 1github-code Web Component — Simon Willison
- 2Prompt gist for the github-code component — GitHub Gist
- 3Live github-code component demo — tools.simonwillison.net
- 4github-code Web Component — Simon Willison