
2003 年の WordPress を 2026 年のスタックで動かしてみた週末(が何回かあった)話。2003 年のコードには手を入れない、というルール付きで。
TL;DR
WordPress 最初期のタグ付きリリース WordPress 0.71-gold(2003 年 5 月)— b2/cafelog の流れをくむ、Hello Dolly 以前、テーマ以前、プラグイン以前、いまのループ概念以前のコード — を PHP 8.3 / MySQL 8 / Docker / npm workspaces / PHPStan / Playwright / カスタムブロックエディタ の上で動かしてみた。
ルールは 「2003 年のコードを書き直さない」。動かすのに必要な最小限の変更にとどめて、モダンなものは全部その外側に置く方針で。
ブラウザでそのまま動かせるようにもしておいた。
WordPress Playgroundと同じく、インストール不要・サーバー不要、PHP 8.3 を WebAssembly にコンパイルし、DB はブラウザ内 SQLiteにしている。

このボタンから起動できるので、ぜひWordPress 0.71 を体験してみてほしい。
なぜやってみたのか
WordPress は今月で 23 周年になる。多くの人は 0.71 を実際に触ったことがないと思う。b2/cafelog からの fork、Matt氏による6月9日のアナウンス投稿 — 初期 WordPress の話は読み物としては存在するのだが、実際に試せる環境はもうない。
そこで、試せる環境を作ってみたいと考えた。
ただ、PHP 4 時代のコードは PHP 8 では起動しない。
ereg() も ext/mysql も PHP4 形式コンストラクタも、もう無い。
MySQL 8 の strict モードも、2003 年の b2/cafelog が書いた SQL は半分がエラーになる。
ログイン画面に辿り着く前に Fatal の壁を乗り越えなければならない。
・・・そりゃそうである。
そこで方針を 「動くのに必要な最小限だけ近代化する。」 とした。
2003 年の表層はそのまま、外側を 2026 年のツールチェーンで包む格好だ。
「何が見えてくるかをやってみたい」というプロジェクトである。
「コードに触らない」ルール、譲った箇所だけ書いておく
src/ の中で、どうしても触らざるを得なかったものを並べておく。
ext/mysql→mysqli(mysql_*系は PHP 8 にはもう存在しない)- POSIX
ereg*→ PCRE - PHP4 形式の
function ClassName()コンストラクタ →__construct() - 廃止・改名された PHP 組み込み関数とスーパーグローバル
- MySQL 8 の予約語、
sql_mode=STRICT_*、文字セット周りの諸々 - セキュリティ周り(SQL インジェクション・XSS・CSRF・認証/セッション・アクセス制御・ファイルアップロード・情報漏洩)
最後の項目だけは譲れなかった。
WordPress 0.71 は「プリペアドステートメント」という言葉がまだ一般化していない時代のコードだ。
素のまま公開インターネットに置いたら、重罪に等しい。
そんなわけで、0.71 はあくまで ローカル限定の成果物 として扱うことにして、公開は別ルートを通すことにした(後述)。
それ以外のモダン要素(Docker・PHPUnit・PHPStan・Playwright・WPCS)は、すべて src/ の 外側 に置いた。2003 年のディレクトリは可能な限り 2003 年のまま残してある。
ちなみに PHPStan は level 0 で エラー0 件、WPCS(WordPress-Core)も エラー0 件 で通している。
2003 年の b2/cafelog コードに対して、である。これはちょっと気持ちよかった。
現在のWordPress風でツール群に命名した
wp-cli / wp-env / wp-now を触ったことがあれば、構造はすぐに馴染むと思う。(意図的に模倣してる)
2026 の WordPress このプロジェクト 内容 wp-cli071-clinpx 071 <command>、0.71 用 CLI(静的書き出しも含む)wp-env071-envnpx 071-env start、PHP 8.3 / MySQL 8 の Docker 環境マネージャwp-now / Playground071-nowブラウザ内 WordPress 0.71、PHP-WASM + SQLite
npm run setup で一括導入(npm workspaces・ブロックエディタの Vite ビルド・Composer の PHP 開発ツール)、npx 071-env start で Docker 起動。
wp-install.php を開くと、2003 年の WordPress インストーラが 2026 年の laptop の PHP 8.3 から配信されている、という光景が拝める。
なかなか不思議な感覚なので、ぜひ一度試してみてほしい。
071-now(ブラウザで動く 0.71)
この記事で 1 つだけクリックしてもらえるなら、playground のリンクをお願いしたい。
0.71 のサイト全体が ブラウザのタブの中だけ で動く。PHP 8.3 を WebAssembly にコンパイルし、DB は SQLite、サーバー側は何もしない。
WordPress Playground と同じ仕組みを、23 年前のコードに向けた格好だ。
正直なところ、0.71 を動かすにはこれが一番安全な方法でもある。
何も外に晒されず、何もサーバーに永続化されない。
好きなだけ壊して、リロードしてやり直してほしい。
・・・ブロックエディタも乗せてみた
この章は週末を 1 つ消し飛ばした話になる。
PHP8.3とMySQL8でWordPress 0.71が動いたあと、少し欲が出てきてしまった。
「どうせならブロックエディタを組み込んでみよう」
もちろん、WordPress 0.71 に REST API は無い。
テーマシステムも無い。wp_enqueue_script も無い。
現代の Gutenberg は 0.71 に存在しない前提のかたまりで作られているので、そのままの移植は不可能である。
ただし、@wordpress/block-editor(プラグイン本体ではなく、React パッケージの方)を最小限のカスタムバックエンドに乗せて、ブロックマークアップを既存の post_content カラムに保存し、0.71 既存のフロントエンドに描画させる、というのは できた。

従来の b2edit.php エディタはデフォルトのままで、ブロックエディタは実験的な代替手段として横に置いてある(置き換えではない)。
つまり、いまのループ概念より古いコードベースの上で、投稿をブロックで書いて保存すると、0.71 のフロントエンドは何も変わったことに気付かないままレンダリングする、という状態である。
調査メモは docs/gutenberg-investigation.md に書いておいたので、継ぎ目の在り処を確かめたい人はそちらをどうぞ。
※もちろん、この記事は0.71に組み込んだブロックエディターで書いている。
テストを書く理由 — 古いコードには潜んでいるかわからないから
古いコードは触ってみないとわからない挙動の塊なので、テストを敷いておいた。
- PHPUnit 94 件 — 2003 年コードのうち単体テスト可能な部分(テキスト整形、同梱の Textile パーサ、日付/URL/数値ヘルパー、
get_postdata()/get_userdata()/get_the_category()などの DB 依存ヘルパー)を、偽$wpdbを使って網羅。 - Playwright の E2E — 実ブラウザから、稼働中の Docker ブログの実管理画面・実フロントエンドを叩く。ログイン、投稿の作成/編集/削除、カテゴリの追加/削除、トップ、単一投稿(
?p=)、カテゴリ(?cat=)、月別アーカイブ(?m=)、RSS 2.0 フィード。すべてのページで PHP のFatal/Warning/Deprecatedが ゼロ であることを assert している。 - E2E が投入するデータは
E2E:接頭辞で識別、名前で削除するため、再実行で既存投稿を消すことはない。
安全に公開する — 静的書き出し
せっかく動作したら、やっぱりそれを使って公開したいという人が出てくるかもしれない。
そこで、一番安全な方法でWordPress 0.71を公開するフローも用意しておいた。
想定している運用フローは次の通り。
- ローカルの Docker ブログで投稿を書く。
npx 071 exportでサイト全体を静的 HTML にダンプ。- 静的ファイルだけを公開先(GitHub Pages / S3 / Cloudflare Pages、なんでも)へアップロードする。
公開サーバーは PHP も MySQL も動かさない ため、2003 年のコードベースが晒されることはない。
0.71 の出力をインターネット近くに置くなら、これ以外の方法を選ぶ理由が思いつかなかった(し、今でも思いつかない)。
静的ファイルへの書き出しは以下のコマンドで可能だ。
$ npx 071 export
触ってみてわかった、WordPress の「歴史」
実際にコードを開いて触ってみて、はっきり感じたことがいくつかある。
まず、0.71 には 固定ページが無い。投稿とカテゴリがあるだけだ。
コメントとトラックバックはあるが、テーマも、メディアライブラリも、ウィジェットも、プラグインの仕組みも、当然 REST API も、無い。
もっと言うと、「ダッシュボード」もない。/wp-adminにアクセスして表示されるのはエディタと、記事一覧だけだ。

「WordPress は CMS だ」と当たり前のように言われるが、0.71 のコードを読むと、これは まさしくブログツール であった、という事実がコードの肌触りとして立ち上がってくる。
そして、そこから 全世界の Web サイトの 40% 以上 を支えるところまで育った。
20 数年で、このコードからこのシェアまで。20 年分の歴史の両端が同じ git checkout に入っている状態を手で触っていると、いままで頭で知っていたつもりの「WordPress が大きくなった」という事実が別の解像度で入ってきた。
それからもう 1 つ — ブロックエディタの組み込みやすさ にも驚いた。
@wordpress/block-editor は思っていたよりずっと独立していて、REST API もテーマシステムも前提にしていない。
保存と読み込みさえ繋いでやれば、2003 年のコードベースの上にでも乗ってくれる。
Gutenberg プロジェクトが「単体で外に持ち出せるエディタ」として相当な労力で作り込まれていたことが、ここで初めて腑に落ちた。
・・・ところで、page-*.php の話を少しだけ
少し前、page-*.php まわりでちょっとした議論があった。
詳しくは ベクトルさん の 「なぜ page.php なのか?」 と、Capital P の 「page-*.php は問題なのか?」 を読んでもらうのが早い。
0.71 のコードを触りながらあの議論について、ふと考えたことがあったので書き残しておきたい。
冒頭にも書いた通り、0.71 には固定ページが無い。
0.71 はまさにブログツールだった。
そこから WordPress は、いつの間にか「コーポレートサイトから、ECサイト・会員サイト、ランディングページも何でも作れる、無料のサイト構築ツール」として確立されていった。
クライアントワークの現場でも、企業サイトの選択肢としてまず名前が挙がる存在になって久しい。
ただ、その間も WordPress の本質は変わっていないと思う。
WordPress.org が掲げるミッションは “Democratize Publishing” — 「出版の民主化」だ。

ブログツールに見えるか、サイト構築ツールに見えるかは、その時々の表層の違いに過ぎなくて、根っこは20 年以上同じ場所にある。
実務に目を向けると、「WordPress を持ちたい」が起点で相談に来てくれるクライアントは、ほぼいない。
クライアントが欲しいのはWebサイトであり、自分でコンテンツを更新できる仕組みであって、WordPress というプロダクトそのものではない。
「自分で更新できる」「自分で発信できる」という、その「出版の民主化」の価値を、クライアントに渡したいと思った時にWordPressを提案したいと考えている。
テンプレートに HTML をベタ書きしたものを納品するというのは、その価値の受け渡しの逆を行く行為だと思っている。
だとすれば、提案する側の責任として、「WordPress とは何なのか」「どんな仕組みで動いているのか」を、もっと知っておきたい。
せっかくオープンソースで、ソースコードまるごとが目の前に置いてあるのだ。
研究することも、遊んでみることも、誰にでも許されている。
今回 0.71 を引っ張り出して 2026 年のスタックに乗せ直してみたのも、その「遊んで学んでみる」の一形態のつもりだ。
どうせ薦めるなら、もっと詳しくなろう。自戒も込めて、そう思っている。
これは何ではないか
念のため書いておくと、これは本番ソフトウェアではない。
実運用に向けた 0.71 のハードニングでもない。
「0.71 でブログを運用しよう」という提案でもない。
README にも太字で書いてあるが、ここでも繰り返しておく — やめておいてほしい。

たまたま動かせる考古学プロジェクト、というのが一番近い表現だと思う。
2003 年の WordPress を、その生息環境で読んで、モダンな道具をそっと上に重ねるためのもの。
WordPress 7.0 がリリースされたタイミングで、23 年前の 0.7 を動かしてみた。それだけの話だ。
試してみてほしい
興味を持ってくれたらぜひ、このボタンから2026年に突如蘇ったWordPress 0.71を体験してみてほしい。
Gitリポジトリ
https://github.com/mt8/wordpress-0.71-gold
ローカルでの起動方法
$ git clone https://github.com/mt8/wordpress-0.71-gold
$ cd wordpress-0.71-gold
$ npm i
$ npm run setup
$ npx 071-env start
新品の laptop から 2003 年のインストーラを拝むまで 約3 分。
同じようなことに興味がある人の参考になれば嬉しい。
WordPress、23 歳おめでとう。
最初のリリースは、まだ起動するぞ。