Memo

5/20/2026

WordPress 0.71、23 年ぶりの Hello World [General] — admin @ 4:44 am

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/ の中で、どうしても触らざるを得なかったものを並べておく。

最後の項目だけは譲れなかった。

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 既存のフロントエンドに描画させる、というのは できた

まさかのWordPress 0.71に召喚されてしまったブロックエディターさん

従来の b2edit.php エディタはデフォルトのままで、ブロックエディタは実験的な代替手段として横に置いてある(置き換えではない)。

つまり、いまのループ概念より古いコードベースの上で、投稿をブロックで書いて保存すると、0.71 のフロントエンドは何も変わったことに気付かないままレンダリングする、という状態である。

調査メモは docs/gutenberg-investigation.md に書いておいたので、継ぎ目の在り処を確かめたい人はそちらをどうぞ。

※もちろん、この記事は0.71に組み込んだブロックエディターで書いている。

テストを書く理由 — 古いコードには潜んでいるかわからないから

古いコードは触ってみないとわからない挙動の塊なので、テストを敷いておいた。

安全に公開する — 静的書き出し

せっかく動作したら、やっぱりそれを使って公開したいという人が出てくるかもしれない。

そこで、一番安全な方法でWordPress 0.71を公開するフローも用意しておいた。

想定している運用フローは次の通り。

  1. ローカルの Docker ブログで投稿を書く。
  2. npx 071 export でサイト全体を静的 HTML にダンプ。
  3. 静的ファイルだけを公開先(GitHub Pages / S3 / Cloudflare Pages、なんでも)へアップロードする。

公開サーバーは PHP も MySQL も動かさない ため、2003 年のコードベースが晒されることはない。

0.71 の出力をインターネット近くに置くなら、これ以外の方法を選ぶ理由が思いつかなかった(し、今でも思いつかない)。

静的ファイルへの書き出しは以下のコマンドで可能だ。

触ってみてわかった、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” — 「出版の民主化」だ。

https://wordpress.org/about/ より

ブログツールに見えるか、サイト構築ツールに見えるかは、その時々の表層の違いに過ぎなくて、根っこは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

ローカルでの起動方法

新品の laptop から 2003 年のインストーラを拝むまで 約3 分。

同じようなことに興味がある人の参考になれば嬉しい。

WordPress、23 歳おめでとう。
最初のリリースは、まだ起動するぞ。

Hello World from WordPress 0.71 — 23 Years Later [General] — admin @ 4:10 am

A weekend (well, several weekends) of running 2003’s WordPress on a 2026 stack — with one rule: don’t rewrite the 2003 code.


TL;DR

I took WordPress 0.71-gold — the very first tagged release of WordPress from May 2003, the descendant of b2/cafelog, predating Hello Dolly, themes, plugins, and the loop as we know it — and got it running on PHP 8.3 / MySQL 8 / Docker / npm workspaces / PHPStan / Playwright / a custom block editor.

Rule of the game: don’t rewrite the 2003 code. Only change what’s strictly necessary to make it run. Everything modern lives in the environment around it.

I also made it runnable straight from a browser.

Same idea as WordPress Playground — no install, no server, PHP 8.3 compiled to WebAssembly, with in-browser SQLite as the database.


The button below boots 0.71 right there in your tab. Please give it a click.


Why?

WordPress turns 23 this month. Most people have never actually clicked around in 0.71. The b2/cafelog fork, Matt's June 9th announcement post — the early WordPress story exists as reading material, but there is no environment left where you can actually try it.

So I figured I’d build that environment.

The problem: PHP 4-era code does not boot on PHP 8.

ereg() is gone. ext/mysql is gone. PHP4-style constructors are gone.

MySQL 8’s strict mode rejects half of what 2003 b2/cafelog wrote.

You hit a wall of fatals before you ever reach a login screen.

…which, fair enough.

So the policy became: modernize only what’s needed to boot.

Keep the 2003 surface as-is. Wrap it in a 2026 toolchain.

A “let’s see what’s underneath” kind of project.

The “don’t touch the code” rule, with the small print

A short list of what had to change inside src/:

That last one isn’t negotiable.

WordPress 0.71 was written before “prepared statement” was a phrase people said out loud.

Running it as-is on the public internet would be close to a felony.

So 0.71 is treated as a local-only artifact, and publishing goes through a different path (more on that later).

Everything else modern (Docker, PHPUnit, PHPStan, Playwright, WPCS) lives outside src/. The 2003 directory stays as 2003 as possible.

For what it’s worth: PHPStan is at level 0 with 0 errors, WPCS (WordPress-Core) is also at 0 errors.

On 2003 b2/cafelog code. That felt good.

Tooling, named in the modern WordPress dialect

If you’ve used wp-cli / wp-env / wp-now, the layout will feel familiar straight away. (The resemblance is intentional.)

Modern WordPressThis projectWhat it does
wp-cli071-clinpx 071 <command> — CLI for 0.71, includes static export
wp-env071-envnpx 071-env start — PHP 8.3 / MySQL 8 Docker env manager
wp-now / Playground071-nowWordPress 0.71 in your browser — PHP-WASM + SQLite

npm run setup installs everything in one go (npm workspaces, the block-editor Vite build, the Composer dev tooling). npx 071-env start boots Docker.

Open wp-install.php and you’re looking at the 2003 WordPress installer, served by PHP 8.3 from a 2026 laptop.

It is a strange feeling, and I do recommend it.

071-now (0.71 in the browser)

If you only click one thing in this post, please make it the playground link.

The whole 0.71 site runs inside the browser tab itself. PHP 8.3 compiled to WebAssembly, SQLite as the database, server side does nothing.

Same machinery as WordPress Playground, pointed at a 23-year-old codebase.

Honestly, this is also the safest possible way to run 0.71.

Nothing exposed, nothing persisted server-side.

Break it as much as you want, refresh, start over.

…and a block editor, too

This chapter ate a weekend.

Once 0.71 was booting on PHP 8.3 + MySQL 8, things got a bit greedy.

“As long as we’re here, let’s drop a block editor in.”

Now — WordPress 0.71 has no REST API.

No theme system. No wp_enqueue_script.

Modern Gutenberg is built on a stack of assumptions that simply don’t exist in 0.71, so a straight port isn’t on the table.

But — you can mount @wordpress/block-editor (the React package, not the full plugin) against a minimal custom backend, store block markup in the existing post_content column, and let 0.71’s existing front end render it. And it works.

Gutenberg, somehow summoned into WordPress 0.71.

The classic b2edit.php editor stays as the default; the block editor sits next to it as an experimental alternative (not a replacement).

So: on a codebase that predates the WordPress loop as we know it, you can write a post in blocks, hit save, and the 0.71 front end renders it without noticing anything has changed.

Investigation notes are in docs/gutenberg-investigation.md if you want to see where the seams are.

※ And yes — this post was written in the block editor mounted on 0.71.

Tests, because there’s no telling what’s hiding in old code

Old code is full of behaviour you only learn by poking. So I laid down a safety net.

Publishing safely — static export

Once it works, some people will inevitably want to actually publish with it.

So I built in the safest possible publishing flow for WordPress 0.71.

The intended workflow:

  1. Write posts in the local Docker blog.
  2. npx 071 export dumps the whole site to static HTML.
  3. Upload only the static files anywhere — GitHub Pages, S3, Cloudflare Pages, whatever.

The public server runs no PHP and no MySQL, so the 2003 codebase is never exposed.

If 0.71 output is going anywhere near the internet, I couldn’t think of any other reasonable way to do it (and still can’t).

The static export is just one command:

What touching the code taught me about WordPress’s history

A few things became unavoidable once the code was actually in my hands.

First: 0.71 has no pages. Just posts and categories.

Comments and trackbacks exist — but there are no themes, no media library, no widgets, no plugin system, and obviously no REST API.

And going further: there’s no “Dashboard.” Hit /wp-admin and what you get is the editor and a post list. That’s all there is.

“WordPress is a CMS” is something we say automatically. Read the 0.71 code, though, and the truth rises right up off the page: this was, very precisely, a blog tool.

And from there, it grew to power over 40% of the entire web.

Twenty-something years from that codebase to that share. With both ends of that arc sitting in the same git checkout under my hand, the abstract fact of “WordPress got big” landed at a completely different resolution than I’d held it in my head before.

The other surprise: how cleanly the block editor drops in.

@wordpress/block-editor turned out to be far more standalone than I’d assumed. It doesn’t insist on the REST API. It doesn’t insist on the theme system.

Wire up save and load against any backend you’ve got, and it will happily run — even on top of a 2003 codebase.

The amount of work the Gutenberg project must have put into making the editor portable like that — that only really landed for me here, on the other side of the experiment.

Democratize Publishing

There’s something else this project pushed me to revisit.

0.71 has no pages, as I said. 0.71 was, very precisely, a blog tool.

From there, WordPress quietly grew into “the free thing you build corporate sites, e-commerce sites, membership sites, and landing pages with.”

Even in client work, it has been a long time since WordPress was anything but the first name on the table when someone needs a company site.

But underneath, I don’t think WordPress’s essence has actually changed.

WordPress.org’s stated mission is “Democratize Publishing” — and I think that’s still the whole game.

via wordpress.org/about

Whether WordPress looks like a blog tool or a site-building tool in any given decade is a surface difference. The root has been in the same place for 20+ years.

In day-to-day client work, almost nobody walks in saying “I want a WordPress.”

What clients actually want is a website — something they can update themselves. WordPress, the product, is never the goal.

The reason we still propose WordPress is that we want to hand them that “you can publish on your own” — that little piece of “Democratize Publishing.” That’s the actual value being transferred.

And because that value lives in the open source itself, getting more familiar with the codebase — reading it, poking it, breaking it — is part of how we get better at the job. The whole thing is sitting right there in public.

Studying it, playing with it — both are permitted, for anyone.

Pulling 0.71 out and dropping it onto a 2026 stack was, in part, just my own form of “play and learn.”

If we’re going to recommend WordPress, we may as well know it well. Saying that as much to myself as to anyone else.

What this isn’t

For the record: this is not production software.

It is not a hardening of 0.71 for real use.

It is not a “you should run your blog on 0.71″ pitch.

The README says this in bold, and I’ll say it again here — please don’t.

The closest honest description is: an archaeology project that happens to be runnable.

A way to read 2003 WordPress in its own habitat, with modern tooling resting gently on top.

Done with 0.7 on WordPress 7.0’s release day, twenty-three years later. That’s all this really is.

Try it

If any of this sounds interesting, please give the button a click and meet WordPress 0.71, unexpectedly back from 2003, running in 2026.

Repo

https://github.com/mt8/wordpress-0.71-gold

Local setup:

About 3 minutes from a fresh laptop to staring at the 2003 installer.

Hope it’s useful for anyone working on something similar.

Happy 23rd, WordPress.
The first release still boots.

0.004 Powered by WordPress