自分用のMarkdownエディタを、Geminiと設計して作った話

今回は、自分用に作ったブラウザ完結型のMarkdownエディタ「LiteMD」について、 作る前にGeminiと要件を詰めていったときの話を残しておきます。

コードの解説というより、「個人開発の仕様を、AIと壁打ちしながらどう固めたか」の記録です。 前半が作る前の設計対話、後半が組み上がってから公開までに変わった部分。

きっかけ

やりたかったことはシンプルで、

  • 左に書く欄、右にプレビュー
  • ブラウザだけで完結(サーバは持たない)
  • 書いたものは .md でダウンロードできる

これだけ。自分用に欲しかったのと、あわよくば広告収入がもらえたら嬉しいな、くらいの温度感でした。

ただ、いざ作り始める前に「決めておくべきことって他に何があるっけ」が自分だと抜ける。 そこでGeminiに、実装に入る前に詰めておくべき点を洗い出してもらうことにしました。

Geminiに要件を詰めてもらう

「webでmarkdownをプレビューしながら編集できるアプリを作りたい。バックエンドは持たず、mdでダウンロードできる形にしたい」

みたいなざっくりした相談から始めて、向こうから質問を返してもらう形で進めました。 返ってきた論点がわりと的確で、自分の頭の中の穴が埋まっていく感覚。

出てきた論点はだいたいこのあたり。

  • 同期スクロールはやるか
  • シンタックスハイライトや行番号は自作か、既存ライブラリ(CodeMirror / Monaco)か
  • 対応するMarkdownのフレーバー(GFMのテーブルやタスクリストまで見るか)
  • プレビューのXSS対策(サニタイズをかけるか)
  • オートセーブ(localStorage)を持つか
  • 画像をどう扱うか

「バックエンドを持たない」という制約が、そのまま設計判断を縛ってくるのが面白いところでした。

決まった構成

やり取りの結果、技術スタックはこう落ち着きました。

  • フレームワーク: React (Vite) + TypeScript
  • スタイリング: Tailwind CSS
  • エディタ: CodeMirror 6
  • Markdownパース: marked(GFM対応)
  • サニタイズ: DOMPurify
  • ホスティング: Vercel(静的サイト)

CodeMirror 6を選んだ理由は、軽くて、左右ペインの同期スクロールを実装しやすいと勧められたから。 このへんは自分で全ライブラリを触り比べたわけではなく、Geminiの推奨に乗った部分です(※なので選定理由は受け売りが混じっています)。

割り切ったところ

バックエンドを持たない制約で、いくつか素直に割り切りました。

画像はローカルアップロード非対応、外部URLのみ サーバに画像を保存できないので。ドラッグ&ドロップでBase64埋め込み、という手もあるにはあるけど、初期リリースでは複雑化を避けて ![alt](URL) のテキスト指定だけにしました。

PDF出力は「印刷」で代替 専用のPDF書き出しは持たず、ブラウザの印刷(Ctrl+P)を使ったときに @media print でエディタや広告を隠して、プレビュー部分だけがきれいに出るようにする方式。機能を増やさずに要求を満たせるので、これは気に入っています。

モバイルはタブ切り替え メインはPC用ツールという位置づけ。ただスマホで開いたときに左右50%分割のままだと厳しいので、エディタ/プレビューをタブで切り替える形で最低限だけ対応。

セキュリティは最初に決めておく

プレビューでユーザーの書いたMarkdownをHTMLに変換して表示する以上、XSSは避けて通れないところ。 markedで変換したあと、必ずDOMPurifyを通してからDOMに入れる、というのを最初にルールとして固めました。

バックエンドなしでも、ここはサボらないようにしています。


ここからリリース版:出す前に変わったところ

ここまでが作る前の話。 実際に組み上がったものを触りながら、公開できる状態か見ていくと、細かい抜けがそれなりに出てきます。

置き場所がCloudflareになった

設計時点ではVercelに置くつもりでしたが、公開しているのはCloudflareです。

理由は単純で、広告を出せるかどうかでした。 無料の範囲で使う前提だと広告を載せられないと分かったので、それができる置き場所に移した形です。

このLiteMDが最初のツールだったので、以降に作ったものもそのままCloudflareに置く流れになりました。

スクロール同期は、入れたうえで切れるようにした

設計対話では「やるかどうか」の論点として挙がっていた同期スクロール。 実物には入っていて、さらに設定でオフにできるようにしてあります。

長い文章を書いていると、プレビュー側だけ動かして確認したい場面があるので。

設定の項目を増やした

同期スクロールのオンオフを置くために設定ダイアログを作ったんですが、 項目が1個しかない設定画面というのも、開いたときにさすがに寂しい。

なので「他にあったほうが便利なもの、できることって何かある?」と聞いて、出てきた中から足していきました。

  • 行番号の表示・非表示
  • 右端での折り返し
  • タブ幅
  • フォントサイズ
  • オートセーブそのもののオン・オフ

どれも大した実装ではないんですが、置き場所ができると中身が欲しくなる、というのは分かりやすい動機だなと。

日本語と英語を切り替えられるようにした

UIの表示言語を日英で切り替えられます。 Markdownエディタは日本語圏だけのものでもないので、入れておいて損はないかなと。

.mdの読み込みにも対応した

設計時点では「.mdで書き出せること」しか考えていませんでしたが、 書き出せるなら読み込めないと片手落ちなので、インポート側も付けました。

サイズ上限は5MBで、読み込むと今の内容が上書きされるので、その前に確認ダイアログを挟んでいます。

変えなかったところ

画像の扱い(外部URLのみ)と、印刷でPDF代わりにする方式は、設計時のまま残っています。 自分の使い方だと困る場面がなかったので、手を入れていません。

まとめ

作る前にAIと要件を詰めておくと、「あとで気づいて手戻り」がだいぶ減る印象でした。 特に、自分ひとりだと見落とす制約由来の判断(画像どうする、印刷どうする)を先に潰せたのが良かったところ。

※もちろんAIの推奨をそのまま鵜呑みにはできないので、選定理由は自分でも軽く裏を取りつつ、です。

ただ、設計対話で決まるのは骨格までで、 組み上がったものを触りながら公開できる状態か見ていくと、細かい抜けはそれなりに出てきます。 スクロール同期を切れるようにしたのも、設定を増やしたのも、インポートを足したのもその工程。

公開してからでも直せるとはいえ、出す前に一度きっちり見る時間は要るなと思っています。

このLiteMD、実は自分が最初に作ったプロダクトなんですが、今いちばん使っているツールでもあります。 AIとやり取りする時間が増えるほど、返ってきたMarkdownを確認したり、手直ししたりする作業が一日で一番発生するようになってきて。 気づけば毎日開いている。

派手な機能はないし、設計も手堅く寄せた小さなツールなんですが、作ってよかったツールで言えば今のところこれがNo.1です。

LiteMD は https://litemd.uekibachidan.com/ で公開しています(2026年6月末から)。