- HTML・JavaScript・CSSを1つのファイルにまとめて実行するHTML toolsの制作経験をもとに、繰り返し現れる設計パターンを整理
- 2年間で150個以上作られた小規模ツールが、実際にどのように作られ保守されているのかを具体例中心に説明
- ビルド工程のない構成とCDN活用により、コピー&ペースト中心の開発フローが自然に形成される
- URL・localStorage・ファイルを開く・ダウンロード・Pyodide・WebAssemblyまで、ブラウザ機能だけで実現できる範囲を拡張
- プロンプトと結果の記録、既存ツールの再構成を通じて、ツールコレクション自体が開発基盤になる流れを強化
HTML toolsの概念と事例
HTML toolの基本構造
- JavaScriptとCSSをインラインで含む単一HTMLファイルで構成
- JSXビルドが必要なReactを使わないため、コピー・再配布が簡単になる
- 必要なライブラリはCDNjsやjsDelivrのようなCDNから直接読み込み、依存関係は最小限に抑える
- コード規模を数百行程度に保ち、保守負担を下げると同時に、LLMが素早く読んで修正できる状態を維持する
Canvas・Artifactsベースのプロトタイピング
- ChatGPT Canvas、Claude Artifacts、Gemini Canvasを使ってHTMLツールを即座に実行しながら初期形を作る方法
- 「No React」という条件を入れ、ビルド工程なしでそのまま動くコードを生成
- JSONを貼り付けるとYAMLに変換する例
さらに複雑になったらコーディングエージェントへ移行
- Claude CodeやCodex CLIを使うと、Playwrightなどによるブラウザテストを含む反復作業を自動化できる
- より複雑なツール(例: Blueskyスレッドビューア)では、このようなエージェントへ「アップグレード」する方式を使う
- simonw/toolsリポジトリに直接PRを作成してツールを追加・更新する
- Webベースのエージェントを使った作業の流れはClaude Code for webの利用動画で確認できる
CDNベースの依存関係管理
- 追加ライブラリを使うときはCDNから読み込む
- LLMのArtifacts/Canvasには許可されたCDN allow-listがあり、「PDF.jsを使う」といった指示でURL構成が行われる
- 必要ならcdnjs・jsDelivrでURLを探してチャットに貼り付ける方式を使う
- npmインストールやビルド工程なしで、1つのHTMLファイルとして動作する
- npm+ビルドステップは、個別ツールを素早くハックしてセルフホストする生産性を下げる
- CDN URLにバージョンが含まれるため、長期的な再現可能性も保たれる
外部の静的ホスティング
- LLMプラットフォーム内ホスティングはサンドボックス制約が多く、外部URLのデータや画像の読み込み、外部リンク機能が制限されることがある
- ユーザー体験の面でも、警告メッセージ・追加読み込み・プラットフォーム宣伝が挟まる問題が起こりうる
- 「No React + CDN」の組み合わせは、ビルドなしでどこにでも置きやすい
- GitHub PagesにHTMLファイルを置けば、すぐ固定URLでアクセスできる
- 大半のツールはsimonw/toolsリポジトリで管理され、tools.simonwillison.netとして提供されている
コピー&ペースト中心の入出力
- 多くのツールは、貼り付けた入力を変換し、再びクリップボードへコピーできるようにする形を中核メカニズムとしている
- モバイルではコピー&ペーストが不便なため、「Copy to clipboard」ボタンをよく追加する
- OSのクリップボードは複数フォーマットを同時に保持でき、JavaScriptのpasteイベントからもこうした「リッチ」データにアクセスできる
- 代表的なツール
デバッグツール
- ブラウザで扱われる実際のデータ構造を確認するための専用ツールも作成
- clipboard-viewer: テキスト・リッチテキスト・画像・ファイルなど、クリップボードデータ全体を表示
- その他のツール
URLに状態を保存
- サーバーDBがなくても、URLに多くの状態を保存できる
- ブックマークや共有を想定するツールではこのパターンが好まれる
- icon-editor: 24×24アイコンの編集状態をURLにそのまま保持
localStorageの活用
- localStorageは、ユーザーのデバイスにデータを永続保存しつつサーバーに露出しないブラウザAPI
- URLに入れにくい大きな状態やAPIキーのような秘密値の保存に使い、静的ホストのサーバーログへ露出するリスクを避ける
- word-counter: 執筆中テキストを自動保存
- render-markdown: Markdown作成中の内容を維持
- haiku: APIキーをlocalStorageに保存し、Webカメラ画像をもとに俳句を生成
CORS可能なAPIの活用
- CORS(Cross-origin resource sharing)は、別ドメインのAPIをブラウザJavaScriptが呼び出せるかを制御する仕組み
- CORSヘッダーが開かれたAPIはHTML toolsにとって有利な資源であり、時間をかけて一覧を集める価値がある
- iNaturalist、PyPI、GitHub(公開リポジトリのコンテンツをraw.githubusercontent.com経由で匿名アクセス可能)、Bluesky、Mastodonなどを利用
- ツール例
LLM APIを直接呼び出す
- OpenAI・Anthropic・GeminiのJSON APIを、CORS経由でブラウザから直接呼び出す
- APIキーをHTMLに埋め込むと漏えいや課金リスクがあるため、localStorageに保存する「secretsパターン」を使う
- ユーザー体験の面では、APIキー発行・貼り付けの手順に摩擦はあるが、実際には動作する
- 例示ツール
ファイルを開くことを恐れない
<input type="file">を使えば、ファイルをサーバーへアップロードしなくてもブラウザ内で直接読み込んで活用できる
- ocr: PDF.jsとTesseract.jsを用いて、PDFをページ画像に変換しブラウザ内でOCRを実行
- social-media-cropper: 画像を開く/貼り付けた後、ソーシャルメディア向け比率(例: Twitter/LinkedIn 2:1、Substack 1.4:1など)でクロップ可能
- ffmpeg-crop: 動画クロップ用ffmpegコマンドを生成
ダウンロードファイルを提供する
- サーバーなしでも、ブラウザ内でファイルを生成してダウンロードとして提供できる
- JavaScriptエコシステムには、さまざまなフォーマット生成ライブラリが存在する
- 例示ツール
PyodideとWebAssembly
- Pyodideは、PythonをWebAssemblyにコンパイルしてブラウザで実行する配布版
- CDNからきれいに読み込めるため、HTML toolsで使わない理由がない
- micropipを通じて、CORS経由でPyPIの純粋なPythonパッケージを追加ロードできる
- ツール例
WebAssemblyでさらに広げる
- Pyodideが成立する基盤はWebAssemblyのおかげであり、他言語で書かれたソフトウェアもブラウザで読み込めるようになる
- Squoosh.appは複数の画像圧縮ライブラリをブラウザ内で提供している
- ツール例
以前のツールを再構成
- 100個以上の単一公開コレクションがあると、LLMがツール群を容易に再構成できる点がもう1つの利点
- ときには過去のツールをコンテキストにコピーして入れたり、コーディングエージェントでは名前で参照したり、例を検索させたりする
- 動くツールのソースコードが、編集ライブラリの利用パターンまで含んだドキュメントの役割を果たし、LLMの成功率を高める
- pypi-changelog制作過程の全文記録: プロンプトトランスクリプト
- 「pypi package explorer」ツールを見るよう指示したうえで、zip-wheel-explorerのソースを読み、PyPI APIでwheelを取得し、バージョン間diffをレンダリングしてCopyボタンを提供する新ツールを作るようプロンプトを構成
- ブラウザでOCRを実行するも参考になる
プロンプト・トランスクリプト記録
- LLM利用記録を保存・公開する習慣によって、自分自身の活用能力を高められる
- チャット型LLMプラットフォームで作ったツールは、share機能を記録手段として使う
- Claude Code・Codex CLIのようなエージェント使用時は、ターミナル全体のトランスクリプトをコピーし、terminal-to-htmlでログをHTMLに変換してGistで共有
- 完成ツールをリポジトリに保存するときは、コミットメッセージにトランスクリプトリンクを含める - 記録集: tools.simonwillison.net/colophon
まとめ
- この1年半、この方法でLLMとHTMLツールを探求する過程は非常に楽しく、HTMLで作れる範囲やLLMの能力を理解するうえで大いに役立った
- 自分だけのツールコレクションを始めるなら、GitHubリポジトリを作り、GitHub Pagesを有効にして .html ファイルをコピーして置くだけで始められる
- おまけとして、Claude Codeとshot-scraperを使ってこの記事のスクリーンショットを追加したトランスクリプトリンクも提供
3件のコメント
HTMLパターン
面白そうですね
すてきですね