A collection of small, single-file HTML tools built with AI assistance. Inspired by tools.simonwillison.net.
- Single-file design: Each tool is a self-contained HTML file with inline CSS and JavaScript
- No build step: No React, no bundlers - just HTML you can open in a browser
- CDN dependencies: When needed, load libraries from CDNs like cdnjs or jsDelivr
- Keep it small: A few hundred lines per tool for maintainability
- Create a new
.htmlfile in thetools/directory - Include these required meta tags for the index to pick up your tool:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Brief description of what the tool does">
<title>Tool Name - Small Tools</title>
<style>
/* Your styles here */
</style>
</head>
<body>
<a href="../">← Back to all tools</a>
<h1>Tool Name</h1>
<!-- Your tool UI here -->
<script>
// Your JavaScript here
</script>
</body>
</html>- Create a PR - the index page is auto-generated from your tool's metadata!
The build script (build.py) automatically:
- Scans the
tools/directory for.htmlfiles - Extracts the title from
<title>(strips " - Small Tools" suffix) - Extracts the description from
<meta name="description"> - Generates
index.htmlwith all tools listed alphabetically - Injects Google Analytics tracking code into all pages (index and tools)
- Creates a
_site/directory with processed files ready for deployment - Copies companion assets (any local file referenced from a tool via
<img src>,<link href>,<script src>, etc.) into_site/at the same relative path, and lists them in each tool'sassetsarray inassets.jsonso downloaders can fetch and verify them
After building, run python3 verify.py to sanity-check the output: it
confirms every file in assets.json exists on disk with a matching size and
sha256, every local reference in a deployed HTML resolves, and index.html
links every tool.
The site includes Google Analytics (GA4) tracking to monitor page visits across all tools.
To configure your Google Analytics measurement ID:
- Open
build.pyand find theANALYTICS_SNIPPETconstant (around line 18) - Replace
G-XXXXXXXXXXwith your actual GA4 measurement ID - Run
python3 build.pyto regenerate the site with your analytics ID - Commit and push the changes
The analytics code is automatically injected into:
- The main index page
- All tool pages (current and future)
This means any new tools added to the tools/ directory will automatically have analytics tracking when the build script runs.
The site automatically deploys to GitHub Pages when PRs are merged to main.
- Build: Runs on every push and PR
- Deploy: Only deploys on merge to
main - URL:
https://dsyang.github.io/vibe-apps/
- Go to repository Settings → Pages
- Under "Build and deployment", set Source to "GitHub Actions"
From Simon Willison's tips:
- Start with AI: Use Claude Artifacts or similar to prototype quickly
- Say "No React": Keep prompts simple to avoid unnecessary complexity
- URL persistence: Store state in URL params for sharing/bookmarking
- LocalStorage for secrets: Keep API keys client-side
- File handling: Use
<input type="file">for local processing - Copy-paste interface: Use clipboard operations for input/output
- A feature similar to Instagram Stories for sharing with family members who are not on Instagram
- A clone of time.is for precise time tracking
MIT