●CONFERENCE — Code w/ Claude, the annual developer conference, kicked off June 22 with keynotes, sessions, and workshops●LIMITS — Claude Code rate limits doubled and Opus API limits rose, making it easier to build reliably at scale●DESIGN — Claude Design updates add design-system alignment, tighter Claude Code sync, and direct canvas editing●SANDBOX — Claude Managed Agents now run in your own sandbox and connect to private MCP servers●MODEL — Claude Fable 5 offers a 1M-token context, always-on adaptive thinking, and 128K output●LINEUP — Opus 4.8, Sonnet 4.6, and Haiku 4.5 lead the lineup; pick the right one per task●CONFERENCE — Code w/ Claude, the annual developer conference, kicked off June 22 with keynotes, sessions, and workshops●LIMITS — Claude Code rate limits doubled and Opus API limits rose, making it easier to build reliably at scale●DESIGN — Claude Design updates add design-system alignment, tighter Claude Code sync, and direct canvas editing●SANDBOX — Claude Managed Agents now run in your own sandbox and connect to private MCP servers●MODEL — Claude Fable 5 offers a 1M-token context, always-on adaptive thinking, and 128K output●LINEUP — Opus 4.8, Sonnet 4.6, and Haiku 4.5 lead the lineup; pick the right one per task
Productionizing a Claude Design Prototype — Single Source, CI, and OGP Auto-Generation
Turn a Claude Design prototype into something that survives production with Claude Code. The call to keep the generated runtime as your foundation, separating logic with a mixin, a single-source data design around a ledger CSV, and CI auto-updates with real-browser OGP capture — implementation included.
The previous article covered splitting Claude Design and Claude Code into diverge and converge. This follow-up steps into the work of turning a prototype into "production you use daily." As the subject, picture a static site I actually built as an indie developer — a dashboard-like page that shows data at a glance.
Four decisions are in play here: how far you can trust an AI-generated artifact as your foundation, how to separate logic, where the source of truth for data lives, and what to automate in CI. Each is a point where you must stop and choose when turning a prototype into something public.
Keep the generated runtime as your foundation, without rebuilding
A Claude Design prototype sometimes ships with a built runtime bundled in — a single JS file like a generated support.js. The reflex is "a prototype is a prototype, rebuild for production," but I deliberately chose to carry the runtime along.
The axis is simple: does the artifact fit your requirements? In this case the conditions lined up.
Zero dependencies, buildless: read it with <script src>, no bundler or install required
The prototype already runs as is; porting to a framework gains little
The runtime is closed in a single JS file, so worst case, it is all there to read
Rather than reflexively avoiding it because "AI generated it," decide by whether its nature fits the need. For a long-lived indie tool, carrying no dependencies was itself a source of reassurance. Had these conditions not lined up, I would have swapped it out. Keep the artifact out of your edit scope and write "generated — do not edit" into your rules to stay safe.
Separate logic with a mixin
Prototypes tend to be all-in-one in a single HTML file. That makes change sites hard to isolate and maintenance heavy. So I pushed most of the implementation into external js/*.js, registered it on a global method bag, and composed it at the end of the main component.
// at the end of js/format.js (idempotent registration, safe to load repeatedly)window.AppLogic = Object.assign(window.AppLogic || {}, { yen(n) { return '¥' + Math.round(n).toLocaleString('en-US'); }, pct(n) { return (n * 100).toFixed(1) + '%'; },});// compose at the end of the main componentObject.assign(Component.prototype, window.AppLogic);
The line I drew: leave only the runtime's contract surface inline — the constructor, lifecycle, and render method it calls by name — and move everything else to external files. "How the screen is described" follows the runtime; "how the code and operations are structured" is mine to decide. Make that boundary clear and the converge phase stays legible no matter how often you touch the detail.
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦The criteria for keeping an AI-generated runtime as your foundation instead of rebuilding, and when a zero-dependency buildless setup pays off
✦Concrete code that separates logic with a mixin while leaving only the runtime's contract surface inline
✦A single-source data design around a ledger CSV, plus OGP auto-generation that captures a real browser with Playwright
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
The most accident-prone thing in visualization is data double-managed between display and aggregation, so the display lies. Design can kill this. I made the human-appended source (a ledger-like CSV) the sole truth, and the data the app reads a derived artifact generated from it.
transactions.csv ─┐
├─ import.mjs ─→ holdings.json (the artifact the app reads)
prices.csv ───────┘
↑ update-prices.mjs (auto-fetch)
The derived artifact forbids direct edits, and a pre-commit hook checks it matches the source. The only thing needing manual updates is appending to the source. Build a structure where the display cannot drift from the facts first, and later features will not break it. Decide that the browser never writes to the repo and that live-fetched values are used only as a failure fallback, and you can keep a dynamic look with no server or DB.
Build "assume it breaks" auto-updates in CI
The part that fetches external values can come down to hitting an unofficial API directly, so you need to be ready for it to break at any time. I isolated fetching to the CI side and kept the browser out of it. A daily run spins fetching, regenerating the artifact, appending a snapshot, regenerating the share image, and deploying through one workflow.
# .github/workflows/snapshot.yml (essentials only)on: schedule: - cron: "0 13 * * *" # 22:00 JST dailypermissions: contents: writejobs: update: runs-on: ubuntu-latest steps: - uses: actions/checkout@<commit-sha> # pin by SHA - run: node scripts/update-prices.mjs # on failure, keep existing values - run: node scripts/snapshot.mjs # commit only when there is a diff
The key is the safe-side design of keeping existing values when a fetch fails. Even if it breaks, you are left with old values, not an empty screen. Pin external Actions by commit SHA to also dodge supply-chain accidents like Action takeovers. Building automation on the premise of "does no damage when it breaks," rather than "everything works," is what paid off in production.
Capture OGP images in a real browser to match exactly
What you end up fussing over is how it looks when shared on social. Crawlers do not run JS, so the share image must be a statically committed PNG; client-side generation is out. So I prepared a standalone page for the image and had CI open it in a real browser to capture the region.
You could redraw with Canvas, but I disliked the glyphs and layout drifting from the site itself, so I chose real-browser capture. Waiting for document.fonts.ready before shooting matches the same glyphs as the body. Sometimes only previewing in a share-validation tool reveals a too-short title or description, so this "verify on the real thing" step was not one I could skip.
A small convention that helped at the finish
Finally, one quiet trick to steady the round trip. Write the project's premises into CLAUDE.md and domain-specific rules into .claude/rules/, and you can start work without re-explaining in every conversation.
# Project foundation
- look → styles.css
- logic → js/
- do not edit the generated support.js (regeneration overwrites it)
- if you change design values, sync the design rules too
Have a pre-commit hook check these conventions mechanically, and you stop the forbidden moves with the system rather than human attention. Even when you hand work to AI, it follows the rules, so docs and implementation drift less. Productionizing, I have come to feel, is less about adding flashy features and more about quietly stacking up this kind of foundation work.
Share
Thank You for Reading
Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.