このブログを、二年間構想していた
「思っていた」というのは正確ではなく、むしろ執念に近い。フロントエンドもバックエンドも書けず、組み込みのコードも書けなかった頃から、それはもうあった。当時はまだ電子工作をいじっていて、たまたま @ushio の の動画とサイトを見つけた。はすごく面白いと思って、自分も欲しくなった。それから半年近くかけて、ゼロから C を覚え、JS と CSS も少しかじって、Hexo で静的ブログを作り Github Pages に置いた。これでようやく自分の小さな居場所ができたわけだ。


その後、@Innei の個人サイトを見つけた。デザインは洗練され、機能も充実していて、一目見ただけで欲しくなり、支援までした。結局使う機会はなかったけれど、そのお金を惜しいとは思わない。おかげで React のソースコードに触れられたからだ。初めて C を見たときと同じように、「所詮はコードじゃないか。大したことはない。いつか自分で一つ書いてやる」と思った。

それは2024年のことだった。そして24年、25年、26年を経て今に至る
それ以来、止まらなくなった。
制御不能
きっかけは、@colmugx の Hexo テーマ Nlvi にライト/ダークの切り替えを付けたい、ただそれだけだった。Dark Reader の JS を使って適当にでっち上げてはみたが、見た目が汚くて納得できなかった。それから CSS の @media を学び、JS による SPA 切り替えへ、TailwindCSS の .dark class へ、SSR の next-theme へと進み、最後は Cookie と Head Sync のインラインスクリプトを、FOUC のちらつきを潰した。四つか五つのやり方を試したことになる。

だが、これは氷山の一角にすぎない。React を知ってからというもの、石器時代のような Hexo と素の JavaScript から Next.js 13 のページルーターまで一気に進み、さらに寄り道して Vue を触り、単一ページアプリケーションのルーティングを研究し、index.html へのフォールバックを理解しようとして、プロジェクトを数え切れないほど作り直した。サーバーを買って Docker、Nginx、ネットワーク接続ストレージをいじり、1Panel の見た目が気に入らず Canopy パネルを自作し、ストレージアレイを研究して RFS を書き、セキュアソケットレイヤー証明書の設定では中国国内の環境で不調を繰り返す acme.sh に苦しめられた末、Rust で Vane と Lazyacme というリバースプロキシまで書いた。もともとはある晩に3時間で書いた800行のごみコードにすぎなかったのに、グループの仲間にけしかけられ、結局4か月を費やして HTTP/3、ゼロコピー、レイヤーモデル、フローエンジンを片っ端から詰め込んだ。その後には Seam というフルスタックフレームワークもあるが、これも底なし沼なので、話はまた今度にしよう。
過剰設計
そしてAI時代が到来し、不安はさらに倍増した。
いちばん皮肉なのは、これらは本来ブログを持ってから、記録しながら作るはずのものだったということだ。ところがブログのほうは、アイデアばかりが増えていくのに、それを書き留める場所がひとつもなかった。一方では内心がずっと自分を責めていた。Vane は完成させると決めたのだから、止めるわけにはいかない、と。もう一方では、進めば進むほど遠ざかっていく無力感があった。自分が何をすべきかはずっと覚えている。ただ、作り上げることができない。よく考えてみると、腰を据えて何かを書くということを、もう随分と長いあいだしていなかった。いま振り返ると、すべては同じひとつのものを指している——過剰設計だ。
当時、実は自分が脱線していると感じていなかったわけではない。Vane?どうせブログもいずれ公開するのだから、リバースプロキシは必要だろう。Seam?どうせ遅かれ早かれフルスタックで書くのなら、先に理想のフレームワークを作ってしまえばいい。一歩一歩に理由があり、そのどれもが「いずれ役に立つ」ものだった。だが問題は、その「いずれ」が永遠に来ないことだ。私は一度も始めてすらいなかったのだから……
失敗
ブログを作るのに、実のところリバースプロキシも自作フレームワークも必要ない。けれど当時の私は、それらを前提条件だと思い込み、いつまでも自分を足止めしながらも筋が通っているように見える理由にしていた。しかし、最初から前提条件などではなかった。本当に必要なことはただ一つ、腰を据えて最初の記事を書くことだった。
実はブログにまったく手をつけていなかったわけではない。むしろ逆で、三度も取り組んだ。

最初に挑戦したのは、まだ Next.js 13 の Page Router が使われていた頃だった。当時の私は、シングルページアプリケーションが何なのかをぼんやり理解している程度で、SSR、SSG、ISR といった概念は何一つ分かっていなかった。それでも、みんなが SSR は良いと言うので、自分も使おうとした。ところが、書き進めるうちに、そもそもこれらのアーキテクチャが何の問題を解決するためのものなのか、まったく理解していないことに気づき、続けられなくなった。その後は Vue 2 の純粋なシングルページアプリケーションに切り替えた。なぜ Vue を選んだのか?恥ずかしながら、名前の響きが良かったからだ。どうせ自分には新しいものだったので、とりあえず試してみようと思った。しかし、それも長くは続かなかった。三度目は React に戻り、素の JSX から始めた。TypeScript を学び、TSX を使えるようになり、CJS と ESM の違いを理解し、リアクティブプログラミングに魅了され、後に手放せなくなる Lucide、Framer Motion、Radix UI といったライブラリも使い始めた——今度こそ、ようやくそれらしい形になった。それでも私は失敗した。本質的には、ただ他人をまねていただけだったからだ。誰かが使っているものをそのまま取り入れ、見た目だけはそれらしくても、なぜそうすべきなのかはまったく理解していなかった。そこに AI の幻覚まで加わり、最低限実用可能な製品として動かすところまでは何とかできても、規模を拡大しようとすると、至る所が落とし穴だらけだった。

その後は React(Remix)Router の Loader、Next.js 15 の App Router、RSC も学んだが、その頃には日々がすっかり忙しくなり、コードを書く時間もほとんどなく、結果として4度目の失敗をする機会もなかった。今思えば、私のサイトは Next.js 13 から Next.js 15 まで書き続け、移行を終えたばかりでまだ公開すらしていないうちに、Next.js 16 beta 1 がリリースされた。
手放そう
「吹っ切れた」と言うのは正確ではない。ただ、疲れたのだ。

AI 時代のテンポは速すぎる。モデルは次から次へと更新され、新しい技術は波のように湧いてくる。私はどんどん焦っていった。立ち止まったら追い抜かれる気がして。いちばん狂っていた頃は一日 16 時間コードを書き、Token だけで一日 $1.9k USD 燃やせた (たしか 2 月ごろ)。体はもうぼろぼろだった。でもそれを全部止めたのは悟りなんかじゃなく、ただ単に疲れただけだ。どんどんきつくなるテンポの中で、最後の一本の藁が乗ったとき、私はかえって吹っ切れた、割り切った、。それでも、これはこれで悪くない。
私は手放すことにした。かつて執着していたものを諦め、ほどほどで切り上げ、明日のことは明日考えるようになった。Vane が完成していない?ひとまず置いておく。Seam はまだ先が長い?また今度やればいい。ブログが完璧じゃない?先に公開する。完全に Vibe Coding へ移行し、問題がなければ触らず、問題が起きたらそのとき考える。
不思議なことに、手を離しても品質は落ちなかった。おそらく、あののプログラミングの日々が無駄ではなかったからだと思う。GPT-2 の時代からすでに AI は使っていたが、当時の自分はまだ一行ずつ真面目にコードを書き、一つひとつの概念を理解していた。あの経験が土台になっている。後の日々は Vibe Coding というより Context Coding で、必要な判断力は残ったままだった。手を離したせいで初歩的なミスをすることも、事故を起こすこともなかった。
これまでの試行錯誤のすべてが、今こうして手放せるだけの土台を与えてくれた。
原点
最終的な解決策は意外にもシンプルだった。すべてを Cloudflare 上に置く。R2 はオブジェクトストレージ、D1 はエッジデータベース、KV はキャッシュ、Worker はサーバーサイドレンダリングに使用する。すべてサーバーレスで、サーバーは不要だ。

この答えは皮肉かって? あまりにも皮肉だ。この「単純な」ゴールにたどり着くまで、延々と回り道をしてきたからだ。かつてはセルフホスティングを計画し、そのためにサーバーを管理し、Docker と格闘し、コンテナの面倒を見ることになった。そこで、管理パネルの Canopy、証明書管理の Lazycert、リバースプロキシの Vane、リソース監視を計装する Twig を作った。たった一台のろくでもないサーバーに奉仕するためだけに、山ほどプロジェクトを作ったのだ。
ストレージも同じだった。オブジェクトストレージは高いと思い、自分のサーバーのハードディスクを使おうとして、データをアトミックに重複排除し、単一ファイルへ統合する VFS「RFS」を作った。さらには1980〜90年代のレジストリという発想まで復活させ、最終的に FUSE 経由でマウントした。結果はどうだったか。より多くの時間を費やして出来の悪い車輪を再発明し、サーバーは一年間も遊ばせたまま。まったく割に合わない商売だった。

結局、ずいぶん遠回りした末にサーバーレスへ戻ってきた。Vercel のコンセプトはよいが、Next.js は好きではない。それに Vercel は魔法が多すぎるし、ミドルウェアを事前コンパイルしてエッジで動かす設計も、結局は分断を生み、CVE までいくつか発生した。それなら、いっそすべてをオリジンサーバーでまとめて動かすほうがましだ。一方、Cloudflare Workers はとてもよく、別の極端に到達している。10 MB 未満の成果物を WASM にコンパイルし、エッジ上で本物のビジネスロジックを動かせる。これこそ私が求めていたものだ。お金がかかること以外に欠点はない――とはいえ、それも欠点とはいえない。結局、節約できる時間はお金なのだから。
少ないほど豊か
この言葉は何度となく耳にしてきたが、その意味を本当に理解するまでに2年かかった。
エンジニアリングの本質に立ち返る。「Make it function, make it correct, then make it exceptional.」ようやく正しい道に戻り、まずは動くものにできた。今のブログは粗末か?粗末だ。未完成か?確かに未完成だ。でも、ないよりはいい。何一つ公開できていないのに、「必要かもしれない」ものを作り続け、目に見えない完璧さばかり追い求めていたら、結局何も形にできない。これは妥協ではなく、エンジニアリング上の取捨選択だ。少なくとも私はもう吹っ切れた。そう、吹っ切れたのだ。一つの細部にこだわるのをやめたら、かえって外へ出られた。スマホの写真には、もう長いこと屋外で撮ったものがなかったので、道端の風景を何気なく一枚撮った——ずっと外に出ていなかったからね(

これまで歩んだ遠回りを振り返って、後悔しているか? していない。自分で試してみなければ、いつまでも腑に落ちないこともある。ましてやAI時代の今、私がかつて歩んだ古い道をたどる機会は、もはやほとんどない。あまりにも多くのワークフローが変わってしまったからだ。それに、このプロジェクトは Taki で、コーディングはすべてAIによるものだ。だが、だからといって長期的に保守できないわけでも、人間味がないわけでもない。そもそもAIを使ったかどうかは重要ではない。それに、私が好きなのはコードを書くこと自体ではなく、何かを作り上げることなのだ……