pre-alpha·MIT licensed·5 of 15 measures for 1.0 still open

A modern PHP engine.
Built from scratch.

Minn fluently speaks with WordPress sites: the same database, the same file layout, the same REST API and WP-CLI verbs. Hosting tools, backups, migrations, and plugins keep working. The code underneath is new, small, and yours to read.

Reads a WordPress database as-is Untouched wp-config.php wp/v2 REST and WP-CLI Minn Admin boots unmodified Diffed live against real WordPress
tests/run-all.sh  ·  engine vs reference, same database
Minn the engine
GET/wp-json/wp/v2/posts/1?context=edit200 · identical
POST/wp-login.php302 · cookie accepted by both
GET/sample-page/200 · body identical
GET/feed/200 · byte for byte
GET/wp-sitemap.xml200 · identical
CLIwp option get siteurlidentical
WordPress the reference, same DB
GET/wp-json/wp/v2/posts/1?context=editthe oracle
POST/wp-login.phpthe oracle
GET/sample-page/the oracle
GET/feed/the oracle
GET/wp-sitemap.xmlthe oracle
CLIwp option get siteurlthe oracle
30,000+ checks green. Every surface is pinned by a captured fixture and diffed live, request by request, against a running WordPress on the same database. Any divergence is a finding.
803
classes in the Minn\ namespace. A clean-room reimplementation
Explore the classes
30,000+
checks across 96 suites, most of them diffed against real WordPress on the same database
Explore the suites
0
Composer packages. Strict-typed PHP, no framework, no build step
1
admin, already built. Minn Admin boots on the engine unmodified
Already on WordPress?

Start with Minn Admin today. Move to Minn when your site is ready.

Minn Admin is a plugin for WordPress sites: a reimagined admin served at /minn-admin/ on the site you have right now. On WordPress software, classic wp-admin stays as a fallback. On Minn there is no wp-admin: Minn Admin is the admin. Everything you learn there carries over unchanged.

  • Install it like any plugin. Free, MIT licensed, no build step, no Pro tier.
  • Live in it. Content, media, comments, users, settings, and more than a hundred plugin adapters that appear on their own.
  • Nothing to relearn. When Minn is ready for your site, the admin you already use comes with it.
The sequence
Phase 0Minn Admin, the daily admin. On WordPress sites today, with classic wp-admin as a fallback.shipped
Phase 1The operational contract. The schema, the file layout, wp/v2 and WP-CLI, so backup and migration tools keep working.done
Phase 2The plugin runtime. Plugins load unmodified, and every function and hook in WordPress 7.1.3 is accounted for.done
Phase 3Existing sites move over. Content sites swap in with one command and back out with one.in 0.1.0
Phase 4New sites from nothing. No WordPress behind them, and extensions that reach past the front end.later

A strangler fig, not a big bang. Each phase is earned by suites, not declared.

The thesis

WordPress is not only software.
It is a coordination standard.

WordPress software remains the dominant web platform because customers, hosts, developers, and now AI agents all coordinate there. The portable unit of site, the frozen schema, the REST API, and the labor pool are the product. The PHP is one implementation of those contracts. Here is what that coordination actually consists of, ranked by how much it matters.

1

A portable unit of site

Files plus a database dump, runnable on any PHP host on earth. Backup, migration, staging, and whole fleet-management stacks exist because the unit is standard.

2

A stable data contract

The posts, postmeta, options, and users schema has not meaningfully changed in twenty years. Backward compatibility is the actual product.

3

An operational surface

WP-CLI, the REST API, the file layout, the config conventions. The layer hosts automate against; the layer that makes hosting WordPress sites an industry.

4

A labor pool

Any freelancer can inherit any WordPress site cold. Choosing a WordPress site is choosing to never be hostage to whoever built it. The customer-control argument is the strongest one.

5

The plugin ecosystem

The weakest leg now, and weakening: AI erodes the long tail. What it does not erode is what a top-tier plugin really is, a maintenance liability transferred to a vendor who ships security releases.

The AI shift sharpens the thesis. When anyone can generate anything on any platform, the rational customer targets the platform where generated work stays portable, inheritable, and operable after the developer leaves. Today that is a WordPress site, because of legs one through four. The question is whether those legs require the WordPress codebase at all.

The graveyard lesson

Every challenger replaced the software and abandoned the contracts.

Ghost, Craft, Statamic, October: none of them dented WordPress, and they all failed the same way. Each replaced the code, which was never the moat, and walked away from the contracts, which were. A clean break means starting over on portability, tooling, hosting support, and the labor pool at once. No product is good enough to win four moats simultaneously.

The correct precedent

You do not ask the world to move. You inherit it through compatibility.

Not “a better CMS”. Nginx against Apache. MariaDB against MySQL. FrankenPHP against PHP-FPM. A from-scratch engine that speaks the incumbent’s interface so precisely that the surrounding infrastructure cannot tell. That is the play.

nginx : apache mariadb : mysql frankenphp : php-fpm minn : wordpress
The play

Two tiers of compatibility, with a hard line between them.

WordPress speaks to three audiences. Minn answers two. The operational contract is sacred. The runtime plugins call into is reimplemented, clean-room, the way Wine speaks Win32. Humans never go through /wp-admin/: Minn Admin is the only UI.

Audience 1 · toolingSpeak

Hosts, backups, CLI.

The schema, the file layout, wp/v2, WP-CLI, feeds, sitemaps, cookies. Kinsta, Disembark and UpdraftPlus operate a Minn site the way they operate a WordPress site.

  • wp_* tables, untouched wp-config.php
  • REST, WP-CLI, probes, login cookies
Audience 2 · plugin PHPSpeak

Unmodified plugins load.

Hooks, options, WP_Query, $wpdb. A site owner does not want ported plugins. They want their plugins.

  • Clean-room runtime, symbol-gated
  • Front end and data. Not a settings screen.
Audience 3 · humansMute

No /wp-admin/.

List tables, meta boxes, the dashboard, the Customizer, Gutenberg-as-an-app: not a Minn surface. Minn Admin is the only UI.

  • /wp-admin/ 302s to /minn-admin/
  • Plugin settings screens are not coming

Browse the lexicon for every family: Speak, Hear, and Mute, sourced from the markdown agents read.

Tier 1 · the operational contract

Indistinguishable at the seams.

  • The database schema. Real wp_* tables, read and written, tolerating serialized-PHP blobs forever.
  • File layout and wp-config.php shape, so backup and migration tooling just works. The engine boots from the file WordPress generated, untouched.
  • wp/v2 REST core routes: posts, pages, media, users, terms, comments, settings, revisions, search, plugins, themes, menus, templates, navigation, global styles, block types, widgets, and batch requests.
  • WP-CLI: the ops verbs (option, user, plugin, theme, db, search-replace) answered by the engine through wp-cli.yml, and every other command, a plugin’s own included, run on the engine’s runtime.
  • Permalinks, feeds, sitemaps, block rendering, block themes. Login, sessions, cookies, and nonces the hosting layer probes, cross-accepted in both directions.
Tier 2 · the plugin runtime, reimplemented

Plugins just work. Layer by layer.

A site owner does not want ported plugins, they want their plugins. So the engine implements the functions plugin code calls: the hook engine, the content and options API, queries, translations, mail and HTTP, admin registrations (not screens). Loaded from active_plugins, unmodified. Every function’s signature is checked against an inventory reflected from the reference, and probe batteries compare behavior with WordPress row by row. The coverage page measures how far it reaches, commit by commit.

E0Inventory: 3,914 functions, 380 classes, 4,075 methods and 2,543 hooks, reflected from the referencedone
E1Hook engine and plugin lifecycledone
E2Content, options, queries, media, cron, HTTP, mail, comments, REST, blocks, translations, the HTML API, $wpdbdone
E3Admin registrations, not screens. add_menu_page records. Nothing is rendered. /wp-admin/ redirects.done
E4Editors: a plugin’s block.json registers and renders. The block and site editors themselves are dead ends: inert stubs, never screens.done
E5Every remaining symbol, one domain at a time, until the whole API is accounted for: each function either implemented and proven by a probe, or a dead end. XML-RPC and the Customizer are dead ends: inert stubs, so nothing fatals.done

Definition of done for 1.0

Every function, class, and method in the WordPress PHP API is accounted for. Each one is either implemented and proven against WordPress by a probe, or marked in the mappings as a dead end Minn leaves behind on purpose: wp-admin screens, the block and site editors, the Customizer, XML-RPC, and anything too old to carry forward. A dead end still answers with an inert stub, so a plugin that calls it does not fatal. On top of that, Kinsta, CaptainCore, Disembark, and UpdraftPlus operate the site the way they operate a WordPress site, Minn Admin boots unmodified, the engine makes no requests to wordpress.org, and every measure in where Minn stands is met. 0.1.0, out now, is the pre-alpha on the way there.

See where it stands today →

How it is built

Capture from the oracle. Implement from the capture. Never from the source.

A parked copy of WordPress runs against the same database as the engine. It is the oracle: every behavior is observed there, recorded as a fixture, implemented from that record, and then diffed live, request by request. WordPress source is never opened while engine code is written.

1

Capture

Boot the reference on the shared database. Curl the exact response, run the exact CLI verb, record it under contracts/fixtures/. Observed behavior is data.

2

Implement

Write the engine from the fixture and the behavioral note. Interface names (routes, columns, keys, verbs) match exactly; every implementation line is original.

3

Prove two ways

A fixture suite pins the captured shape and runs anywhere. A live parity suite diffs the engine against the running reference. Any divergence is a finding, not a flake.

4

Record the contract

Every oracle-learned fact and every honest gap lands in contracts/*.md, machine-checkable and agent-legible. The contract is the product.

# what a milestone looks like
$ curl -sk https://ref.minn.localhost/   # the oracle: WordPress, same database
$ php tests/theme.test.php
  ok   / matches fixture
  ok   / matches reference
  ok   /hello-world/ matches fixture
  ok   /hello-world/ matches reference
  …
  30 passed, 0 failed

$ php tests/rest-parity.test.php
  ok  posts list
  ok  posts _fields id,title,status
  ok  types _fields quirk strips to []
  …
  43 passed, 0 failed

Agent-first is a build method, not a feature

Nobody had done the ops-compatible rewrite because it is an enormous amount of boring, well-specified work. That is precisely what coding agents do well when gated by suites. Every unit ships with a behavioral suite; the suites, not the prose, are ground truth.

Security by declaration

A route’s capability requirement is metadata on the route, mechanically auditable and diffable across releases. Prepared statements only. No unserialize() of untrusted data, ever: serialized blobs are read by tolerant parsers, never executed.

Agent legibility answers the turnover argument

The take-over story for a customer stops being “find another WordPress freelancer” and becomes “point any coding agent at the contracts”.

What the oracle caught

Facts no documentation would have surfaced.

Each one is pinned by a suite that diffs Minn against the running reference, so it cannot quietly drift back.

$wp$ hash → substr($hash, -4)

The cookie key hides in the last four characters.

Modern $wp$ bcrypt hashes sign the auth cookie with the hash’s final four characters, not the old phpass window. The cookie parsed, the session was live, the nonce verified; only the HMAC failed. Brute-forcing the window found it.

bad cookie → 401 · bad nonce → 403

Two failures, two status codes.

A bad cookie is rest_not_logged_in; a bad nonce is rest_cookie_invalid_nonce. Sessions cross over byte for byte: one WordPress minted works on Minn, and one Minn minted works on WordPress.

perm=editable → own posts only

“Editable” means yours, even for admins.

Ask for more than one post type with the editable filter and every status, published included, narrows to the caller’s own posts. Admins too. Minn Admin’s activity feed was built on that behavior, so the engine keeps it.

/wp/v2/types?_fields=name → []

Ask types for one field, get nothing.

On wp/v2/types the payload is a keyed object and _fields filters it whole, so every value yields an empty array. Minn reproduces the quirk by construction, not by special case.

term_taxonomy.count → trusted on read

Term counts are stored, never recounted on read.

WordPress serves each term’s published total exactly as stored. Every write that changes it (publish, unpublish, trash, delete) has to recount, or a stale number leaks into every list response.

6'2" → 6’2″

Feet get a quote mark, inches get a prime.

Texturize turns the apostrophe after a digit into a curly closing quote, but the double quote after a digit into a double prime. Typographically it is half right, and Minn matches it byte for byte anyway.

The license question

Can a WordPress-compatible engine be MIT? Yes.

GPL obligations attach to distributing WordPress’s code or derivative works of it. Minn distributes neither. Compatibility is not derivation. Copyright never protects a procedure, system, or method of operation (17 U.S.C. §102(b)); interfaces, schemas, and protocols are exactly that, and where a compatible route must be named /wp/v2/posts, the expression merges with the idea.

  • Google v. Oracle (2021): reimplementing an API surface for a new platform was fair use.
  • Lotus v. Borland, Sega v. Accolade, Sony v. Connectix: command hierarchies are methods of operation; reverse engineering for compatibility is fair use.
  • In practice: Wine reimplements Win32, Samba reimplements SMB, FerretDB speaks MongoDB under Apache 2.0, and WP-CLI itself is MIT at the heart of the GPL ecosystem.
  • Fork versus reimplementation is the whole question. ClassicPress kept the contracts and stayed a fork: the license came with the tree, so it is GPL forever. A reimplementation written from specifications of behavior is a new work, and its author chooses the license.
The traps, named

What would actually cause a problem.

  • Copied code, including mechanically transformed code. Minn’s predecessor generated its build from WordPress’s own source; that output was a derivative work and could never have been MIT. This is the cautionary tale the whole method is built around.
  • Bundled GPL assets. No core JavaScript, no block-library CSS, no bundled themes, no Dashicons ship in the engine. The block stylesheet you are looking at is Minn’s own.
  • Trademark, not copyright, is the live wire. “WordPress” appears only to identify the software and sites Minn is compatible with, never in the project name or domain.

The hygiene program: spec-first development from fixtures captured on a live instance, implementation from the spec and never the source, a similarity gate against the WordPress tree, tracked provenance for every file, and an hour with an open-source-savvy IP lawyer before the runtime milestone ships. This page is analysis, not legal advice.

Status · pre-alpha

What works today, and what does not.

The engine boots from an unmodified wp-config.php, serves a database WordPress software created, and is written from scratch with only the code it needs to be compatible with WordPress sites. A real site (a client site cloned with the engine swapped in) renders at parity with its parked WordPress software, element by element, in a browser.

Compare the code size: WordPress core next to Minn with Minn Admin, measured from the release zip the same way on both sides and refreshed at each release. Coverage measures how much of the WordPress interface the engine implements, commit by commit. How the PHP reads puts the WordPress idiom next to the Minn shape of the same job.

Working, pinned by suites

  • A visitor can read the site. Permalinks, hierarchies, archives, search, pagination, redirects, 404s: 107 URL shapes at parity.
  • Block themes render as data. Templates, parts, patterns, site-editor overrides, theme.json to CSS with presets byte-identical, and a geometry suite that measures every visible element against the reference in Chrome.
  • Classic PHP themes run. Template hierarchy, wp_head defaults, and live body parity against the reference. Proven on a real site that still uses PHP templates.
  • The admin half. wp/v2 posts, pages, media, users, terms, comments, settings, revisions, autosaves, locks, search, plugins, themes, menus, templates, navigation, global styles, widgets. Minn Admin boots and every view answers.
  • Auth, both directions. Cookies, sessions, nonces, capabilities, wp-login.php, registration, password reset, sign-in throttling, application passwords.
  • The probe surface. Feeds byte for byte, sitemaps, robots, cron, mail, the REST index, the version file tooling parses, and the object-cache.php, db.php, advanced-cache.php and .maintenance files hosts drop in.
  • WP-CLI on Minn, plugin commands and wp eval included, and a one-command minn install / eject that swaps a WordPress webroot over and back, byte for byte.
  • Plugins load as code. On a production site cloned onto the engine, all 25 plugins and the theme load unmodified; on a second clone, all 48 plugins and the theme. 97% of the calls those plugins make into WordPress functions reach one Minn implements (coverage).
  • The round trip. A copy of a real site does the same day of work on WordPress and on Minn, every row each leaves behind is compared, and Minn’s result is handed back to WordPress, which keeps going.
  • Translations. Plugin, theme and core text domains load from .mo and .l10n.php files, scripts get their JSON translations, and a request can switch locale.
  • Never contacts wordpress.org. Update checks, directory search, translations and downloads go to Minn’s own update service, and a Minn release installs only with an Ed25519 signature from a key built into the engine.
  • Fewer database queries. The front page, a post, an archive, a search and the REST posts list each run fewer queries than WordPress on the same database.
  • The source is public. MIT, at github.com/austinginder/minn-engine, with every commit from the first.

Not yet, said plainly

  • No /wp-admin/. Plugin settings screens are not coming. If a plugin only has a wp-admin page, Minn Admin covers it with an adapter, or that page does not exist on the engine.
  • No block editor globals. Editor-side plugin scripts have nothing to attach to.
  • Commerce is limited support. A WooCommerce store’s shop, cart, and checkout run on the engine, and a guest checkout matches WordPress step by step. Running the store is another matter: store management lives in Minn Admin, so payment gateways, shipping and tax extensions, and other commerce plugins that only have wp-admin screens each need a Minn Admin adapter first.
  • The Customizer and XML-RPC are dead ends by design, and Minn runs single sites only: no multisite network.
  • No new sites without WordPress. Minn runs an existing WordPress site: it needs the wp-config.php and the database WordPress created. A site started on Minn from nothing comes later.
  • Not faster than WordPress yet. Pages run fewer database queries than WordPress’s, but every request loads the whole runtime first, so a request takes about a quarter longer on our local benchmark.
  • Agent features are a plan. Route permissions are already data an agent can read. Scoped agent keys, a journal of every write, and a disposable copy of a site to try changes on are designed, not built.
HARD PART · 01

Serialized PHP is forever

Reading real WordPress databases means tolerating serialized blobs in options and postmeta indefinitely. Greenfield sites keep it out of new data; migrated sites drag the long tail in.

HARD PART · 02

The runtime is the long road

Front-end plugins work once hooks and the content API exist. A plugin’s own settings screen is never hosted: Minn Admin adapters own that UI. Editor plugins need the editor globals. “Any plugin” means front end and data, reached layer by layer, not declared.

HARD PART · 03

Commerce is limited support

A store’s front end is plugin code, and plugin code is what the engine runs. Running a store is screens: orders, refunds, gateways, shipping, and tax all live in wp-admin today. Each one has to reach Minn Admin as an adapter before a store can move. Brochure, forms, and content sites come first.

HARD PART · 04

Bus factor

The customer-control argument only transfers once someone other than the founder can maintain the engine. MIT, machine-readable contracts, and exhaustive suites are the mitigation.

Fair questions

Things people ask first.

What is Minn, and what is Minn Engine?

Minn is the project: this site, what you install, the product. Minn Engine is the developer name for the runtime, the way people say WordPress core. Minn Admin is the interface, a plugin that already runs on WordPress and on Minn.

Is this a fork of WordPress?

No. Minn is written completely from scratch, with only the minimal amount of code needed to be compatible with WordPress sites. That is what makes the MIT license possible; a fork would be GPL forever.

Will my plugins work?

Increasingly, on the front end and in data. The engine reimplements the runtime plugins call into, clean-room, and loads them unmodified behind a symbol gate: a plugin that calls a function the runtime lacks is skipped with the reason rather than fataled. A plugin’s own wp-admin settings screen is not hosted. Minn Admin covers that job with an adapter, or that page does not exist on the engine.

Will my host notice?

That is the definition of done, and the point. The webroot keeps index.php, wp-config.php, wp-settings.php, wp-includes/version.php, and wp-content/ exactly where tooling expects them, and wp/v2, feeds, sitemaps, and wp-cron.php answer the way monitors and backup tools probe them. /wp-admin/ redirects to Minn Admin: there is no wp-admin UI. Real fleet tooling is run against a real site until those tools operate it the same way they operate a WordPress site.

Can I go back?

Yes, in one command. minn eject restores the parked WordPress files byte for byte. The database stays yours: a round-trip suite gives WordPress and Minn the same day of work on a copy of a real site and compares every row each leaves behind. Beyond Minn’s own bookkeeping, kept in minn_* options WordPress never reads, each difference it allows is listed and explained, then WordPress takes Minn’s result and keeps going.

Should I move my site to Minn today?

If it is a content site (pages, posts, forms, a classic or a block theme) and you already run Minn Admin, you can try it: preflight names every plugin that will and will not load before anything changes, and one command takes you back. If it is a store, leans on a page builder, or needs a plugin’s own wp-admin screen, not yet. And if nothing on that list matters to you, there is no rush: Minn Admin on WordPress is the same admin, and it is the place to start.

Why PHP?

Because the moat being inherited is PHP hosting. Modern PHP on FrankenPHP-class runtimes is fast, and the infrastructure already speaks it. Modern PHP, 8.3 minimum, no framework, no build step, no dependencies.

Where is the admin?

Minn Admin, a plugin for WordPress sites, is the interface. It boots on the engine unmodified because it never touched wp-admin internals in the first place. On WordPress software, classic wp-admin stays as a fallback. On the engine there is no wp-admin: Minn Admin is the admin. It speaks wp/v2 plus its own namespace, and it works on the WordPress site you have today. Start there.

Where is the source?

The engine is public at github.com/austinginder/minn-engine, MIT licensed, with its whole history. Minn Admin’s source is public too, and its contracts are the same ones the engine serves.

A second engine for WordPress sites.

Try Minn Admin on the site you have today. When 100% of what you do happens in /minn-admin/, consider an engine swap with Minn.

Where Minn stands

Not finished: 5 of 15 measures for 1.0 still open.

Minn 0.1.0 is a pre-alpha release, not ready for production sites. 1.0 ships when the whole PHP API of WordPress is accounted for and proven, and every measure below is met.

What 1.0 still waits on

5 of 15 measures are not met yet, listed first. What the engine is held to beyond the API: the measures from its audit of October 22, 2026, read from the repository at the same commit.

MeasureNowTarget
Not yet: Facade logic reviewedeach function or method that does more than hand over to the engine, judged: move it, delegate it, or keep it with a reason3,132 of 3,749all
Not yet: Doubts the review raised, still openbehaviour that looked wrong, each measured on both stacks, then fixed to WordPress or kept on purpose40
Not yet: Probes that write to the database otherwise than WordPressevery row each probe inserts, updates or deletes, compared1 of 4080
Not yet: REST requests fuzzed against WordPress that answer otherwisegenerated requests to every route, the same on both stacks262 of 14,6070
Not yet: Open items in the runtime notes80
Met: Security findings fixed, each pinned by a check91 of 91all 91
Met: Pages that run no more SQL than WordPressfront page: 26 SELECTs, WordPress 385 of 5all 5
Met: Hooks accounted for2,542 hooks in WordPress 7.1.3100%100%
Met: Hooks proven against WordPress, weighted by plugin installs97%95%
Met: Engine lines the checks runmeasured with unit cases, probes, page and REST requests and every suite, October 23, 202688%85%
Met: WordPress names inside the enginecalls into WordPress functions and its hook API, and references to its classes, in the engine’s own code00
Met: WP-CLI’s own tests that pass on WordPress and not on Minnits feature scenarios run on both stacks0 of 2890
Met: Methods nothing calls00
Met: Leanness ratchets that only fall22 fell; most, Calls into WordPress-named functions: 1,406 to 027 of 27none raised
Met: Full run green30,815 checks passed, October 22, 202696 of 96 suitesevery suite

The leanness ratchets

Counts the style suite holds the engine to, each a ceiling that may only fall: lowered when the code drops below it, never raised. Each starts at the count when the ratchet was added.

RatchetNowStarted
Met: Lifecycle branches (live() calls)2020
Met: Option reads beside the store151159
Met: Raw option writes77
Met: Raw meta writes910
Met: Hand-built post rows88
Met: Hand-built REST links7777
Met: htmlspecialchars outside Html1214
Met: Unfiltered permalink callers3031
Met: Runtime::booted() branches71160
Met: Calls into WordPress-named functions01,406
Met: Calls into the hook API by its WordPress names0384
Met: References to WordPress classes0568
Met: Methods over eighty lines022
Met: Classes over six hundred lines04
Met: Public methods without a docblock0933
Met: Boolean parameters77147
Met: Constructors with six or more parameters2147
Met: array|PostRecord bridges458
Met: Bracket reads of post columns205572
Met: Bracket reads of user columns70132
Met: Bracket reads of comment columns57118
Met: Raw json_encode and json_decode calls11
Met: Routes without a policy6157
Met: Facade functions over fifteen lines1216
Met: Facade functions and methods holding logic3,7533,865
Met: Lines of logic in the facade29,30030,383
Met: wordpress.org request addresses013

The API: 100% accounted for, 100% proven

Every function, class, and method in the PHP API of WordPress 7.1.3, counted at commit 81d04f3d on October 22, 2026. A symbol is accounted for when Minn implements it or the mappings mark it a dead end: something Minn leaves behind on purpose and answers with an inert stub, so a plugin that calls it does not fatal. It is proven when a probe checks its behavior against WordPress.

Accounted for100%
Proven against WordPress100%
KindTotalImplementedDead endStill owedProven
Functions3,9142,96295202,962 of 2,962
Classes3802391410239 of 239
Methods4,0752,3871,68802,387 of 2,387

Dead ends, by design

  • wp-admin screens and includes1,798
  • The block and site editors189
  • The Customizer465
  • XML-RPC and pingbacks197
  • Left out on purpose114
  • Answered Minn’s own way18

Still owed, by area

Nothing: every symbol is implemented or a dead end.

Measured by the engine at commit 81d04f3d on October 22, 2026. Coverage, commit by commit · compat.json

The engine, class by class

803 classes. 101,414 lines of PHP.

Every class in the engine, read from its code by reflection, in 28 namespaces. None of it is WordPress code: Minn is written from the behavior a running WordPress shows, never from its source, which is why all of it can be MIT. Select a namespace or a size to narrow the list, or search it.

87lines in the median class
589lines in the largest, Html\Tags. The style suite fails any class over 600
Allfinal, an enum, or an interface. Nothing waits to be subclassed
246readonly value objects, built once and never changed

Lines by namespace classes beside each name

Classes by size lines per class

Every class

Loading the classes…

    Read from the engine’s code, regenerated whenever it changes (its style suite fails while this is stale). The full API reference · classes.json

    The proof, suite by suite

    30,815 checks. 96 suites.

    From the full run of October 22, 2026: every suite the engine has, counted one assertion at a time. Most compare Minn with WordPress itself, request by request on the same database. Select a group to narrow the list, then open a suite to read its source.

    Where the checks come from

    Every suite

    Loading the suites…

      The suites live in tests/ in the engine’s public repository. The suites on GitHub · stats.json