DEV Community

Cover image for From Chat to Home Screen: Convert Claude Artifacts to PWAs with Zero Config
Baaqar Naqi
Baaqar Naqi

Posted on • Originally published at github.com

From Chat to Home Screen: Convert Claude Artifacts to PWAs with Zero Config

The Problem: Claude Artifacts are Stuck in the Chat

We've all been there. You prompt Claude to build a neat little todo list, a habit tracker, or a dashboard. It spits out a beautiful React/HTML artifact. You play with it, think "This is actually useful", and then... you close the tab.

It's gone.

If you do save the HTML, turning it into a proper installable mobile app is a nightmare:

  • Wrestle with Webpack/Vite configs just to get a manifest.json.
  • Write a Service Worker from scratch.
  • Pray your localStorage doesn't get randomly wiped by the OS when the PWA updates.

I built @baaqar/artifact-to-pwa to fix all of that in one command.

The Solution: npx artifact-to-pwa

No build step. No Android Studio. No Xcode. Just point it at your file or URL.

# From a local React/HTML file
npx artifact-to-pwa ./my-app.jsx

# From a published Claude artifact URL
npx artifact-to-pwa https://claude.site/artifacts/abc123

# Customize it
npx artifact-to-pwa ./app.html --name "My Tool" --color "#ff6b6b" --out ./dist
Enter fullscreen mode Exit fullscreen mode

That's it. It generates a fully production-ready PWA folder:

my-app-pwa/
├── index.html    ← Your app, PWA-ready
├── manifest.json ← Icons, colors, display mode
├── sw.js         ← Service worker (offline support)
├── icon.svg      ← Auto-generated icon
└── README.md     ← One-click deploy instructions
Enter fullscreen mode Exit fullscreen mode

The Killer Feature: Persistent Storage (localStorage → IndexedDB)

Here is where this package actually shines and differs from every other "PWA wrapper" out there.

If your artifact uses localStorage (think: todo lists, streak trackers, user settings, heatmaps), the browser will eventually delete that data. Worse, when a user updates the PWA, the cache clears, and poof—their entire history is gone.

artifact-to-pwa automatically detects localStorage usage and injects a transparent IndexedDB shim behind the scenes.

  • Your artifact keeps using the exact same localStorage API (no code changes needed).
  • All data is actually stored in IndexedDB, which survives PWA updates and OS cleanups.
  • It pre-populates an in-memory cache on load so reads stay lightning-fast.
  • It briefly hides the page on startup until saved data is ready—preventing that ugly "empty state" flash.

You'll see this magic happen in your terminal:

⚡ localStorage detected → auto-migrating to IndexedDB
Enter fullscreen mode Exit fullscreen mode

How to Install It on Your Phone

Once you run the command, deploying it is drag-and-drop simple:

Host Command / Action
Netlify Drag the folder to netlify.com/drop
Vercel npx vercel my-app-pwa
GitHub Pages Push folder contents, enable Pages in settings

Desktop / Android: npx serve my-app-pwa → Open URL → Click the Install icon in the address bar.
iPhone / iPad: Deploy anywhere → Open in Safari → ShareAdd to Home Screen.

Why Bother with a PWA instead of an APK?

  • Cross-platform: Installs on Android, iOS, Windows, macOS, and Linux simultaneously.
  • Always up-to-date: Users get the latest version automatically—no app store review delays.
  • Offline-first: The built-in Service Worker caches all assets.

Supported Formats

This tool is smart enough to detect exactly what you throw at it:

  • Full HTML documents (<!DOCTYPE html>)
  • HTML fragments (partial markup)
  • React / JSX (uses Babel standalone + CDN React—no bundler needed!)
  • Public URLs (embeds them as a full-screen iframe)

Give it a Spin

If you build with Claude, or if you just hate configuring Webpack manifests, give this a try:

👉 Check it out on GitHub

👉 Install from NPM

Drop a star ⭐ if it saves you time, and let me know what you build with it!


Made with ❤️ to keep Claude artifacts alive outside the chat.

Top comments (7)

Collapse
 
nazar-boyko profile image
Nazar Boyko

The localStorage to IndexedDB shim is the clever part, and keeping a synchronous API on top of an async store is a real trick. Preloading a cache on startup makes reads work, that part's clear. What I'm genuinely unsure about is writes. Since setItem has to return right away but IndexedDB persists asynchronously, isn't there a small window where a crash right after a write loses that last value? For a streak tracker that's fine, but for data you'd hate to lose it might be worth a line in the README.

Collapse
 
baaqar_naqi_d8b55ec7077d0 profile image
Baaqar Naqi

You're right. setItem updates the mirror sync, then queues an IndexedDB put(). The transaction commits after the current task finishes, so writes aren't disk-durable for a few milliseconds.

Practically: tab close/navigation is safe (browser waits), but an OS/browser crash in that gap loses the last write. For streak counters/themes, it's negligible. For form drafts or finance, it matters.

I'll add a README caveat and explore transaction.oncomplete for a "synced" indicator in write-heavy apps. Appreciate the precise flag!

Collapse
 
alexshev profile image
Alex Shev

This solves a real gap in the artifact workflow. The moment an artifact becomes useful, the next question is distribution: installability, persistence, offline behavior, and updates. Zero-config PWA export is a nice bridge between demo and actual utility.

Collapse
 
baaqar_naqi_d8b55ec7077d0 profile image
Baaqar Naqi

Thanks. I'm working with multiple artifacts and was wondering how to use them without publishing, thus this came into being.

Collapse
 
alexshev profile image
Alex Shev

That makes sense. Artifacts are useful while you are exploring, but the moment you want to reuse them across devices or share them without publishing friction, they need a deployable wrapper. The zero-config part is what makes that workflow feel less like a separate product step.

Collapse
 
frank_signorini profile image
Frank

This is fascinating! I'm curious how

Collapse
 
baaqar_naqi_d8b55ec7077d0 profile image
Baaqar Naqi

Thanks.
The details are mentioned in the readme file. Feel free to check it out.