Every Webedia brand publishes articles. And almost every brand maintains its own back-office to do it — the same features, rebuilt again and again on five different databases.
Admin international is our research project — today a working proof of concept — betting we can break that cycle: one shared admin any brand plugs into, without touching its database. This is not a technical deep-dive (the specs cover that). It’s the why: the problems, the vision, the principles.
The problem
Take one concept — the article — and walk it across Webedia. Movies publishes articles. Gaming, Food, Travel, Auto, the Pure sites: articles everywhere. A title, a body, tags, a status, a publish date. The feature is the same, or nearly.
But every vertical stores its articles differently. Different databases, different schemas, years of diverging legacy decisions. And because each admin was built directly on top of its database, one concept and five representations gave us five admins.
That costs us, four ways:
- We rebuild the same thing. Article list, edit form, media library, publish workflow. Every brand needs them. Every brand has built them.
- Each copy ages alone. A better scheduling flow shipped in one admin never reaches the other four. The same bug gets fixed five times — or fixed in three and forgotten in two.
- Old admins become no-go zones. Some run on stacks we no longer hire for. They work, but every change is a risk, so nobody touches them.
- Launching is slow. A new brand or country needs an admin — a problem we’ve solved many times — and the estimate is still months, because we start from scratch every time.
These problems feed each other: more admins, more drift; more drift, more legacy; more legacy, slower launches — and slower launches push teams to fork something quickly, creating admin number six. All of it traces back to one root cause: we coupled the admin to the database, so we got one admin per database.
The vision
One sentence: the admin is a product, and our site teams are its customers.
Not a template you copy. Not a framework you inherit and bend. One living codebase, maintained by the transverse team, that any brand plugs into and extends. When it improves, everyone’s admin improves the same day. When a brand launches, the admin is the part that’s already done.
The key idea: we converge on a contract, not on the back-office itself. The old reflex would be to ask every brand to rebuild its admin toward a common UI — five parallel rewrites, again. Instead, each brand implements one contract, and the shared UI follows for free.
Concretely, your database does not change. It stays where it is, and your team writes a connector: a thin layer that adapts your existing schema to the contract’s view of an article. That’s the whole pitch:
You write a connector, you get a back-office.
Not screens, not forms, not an editor. Just an adaptation layer over the database your team already knows better than anyone.
What does a connector look like in practice? It answers the contract’s questions however it wants. When the admin asks “list the published articles”, one connector queries its database directly and maps the rows; another calls the site’s existing REST API; a third goes through a GraphQL layer. When the admin says “publish this draft”, the connector runs its own update logic — its tables, its flags, its cache invalidation. The admin never sees any of that. It only sees articles that match the contract.
This flips the economics. Today every admin is a cost, multiplied by the number of brands. Tomorrow the core is paid for once, and each brand only pays for what makes it unique: its connector, its content types, its quirks.
But shared admins usually die one of two deaths: they become a monolith that pleases no one, or teams fork them “just this once” and the sharing is over. The principles below exist to prevent both.
The principles
1. Contract first, code second
The most durable thing we’re building is not the UI — it’s the agreement between the admin and whatever powers it. The contract says what an article looks like to the admin (fields, blocks, statuses) and what you can do to it (list, search, draft, publish, schedule, archive). It says nothing about tables, columns, or ORMs. You migrate nothing; you adapt what you have.
flowchart LR
A[Shared admin<br/>built once] --- C{{The contract<br/>what an article IS and DOES}}
C --- M[Movies connector] --- MD[(Movies DB)]
C --- G[Gaming connector] --- GD[(Gaming DB)]
C --- F[Food connector] --- FD[(Food DB)]
The contract also locks in how editorial software should behave: saves are explicit actions (publish, schedule, archive), never a blind update; two editors can’t silently overwrite each other; content the admin doesn’t recognise passes through untouched instead of being destroyed. Every brand gets these guarantees, whatever sits behind the contract.
2. Backend-agnostic by design
The admin doesn’t know what it’s talking to. A Movies connector, a Food connector, tomorrow’s stack, or an in-memory fake used in development — all equal, because all honour the same contract.
And you don’t take that on faith. A test suite ships with the contract, and every connector must pass it. Green means the shared admin works on your data. No integration guesswork.
This is also what keeps the product alive long-term: an admin married to one backend dies with it. An admin married to a contract survives every migration underneath it.
3. Extend, never fork
Forking is how shared code dies: the moment a team copies the core to change one thing, the sharing is over. So the core makes forking unnecessary, through a module system.
A module is a small package a brand registers next to its connector. It can:
- Add a whole new section — Food ships a “Recipes” section with its own list and edit screens, alongside Articles.
- Add a custom block to the article editor — Movies adds a “film sheet” block; Travel adds a “destination map” block. Editors use them like any built-in block.
- Add fields to existing screens — Gaming adds a “platforms” field to the article form, or an extra column to the article list.
- Adjust what’s there — rename a section, hide a field a brand never uses.
All of it lives in the brand’s own code and is switched on per site by configuration. The core is never touched — so five brands can each have a different admin, running the same shared core.
We hold ourselves to it too: features you’d assume are “core” are built as modules, through the same extension points we offer everyone else. If we can’t build on our own seams, nobody will.
4. A product has customers
A platform imposed from above gets routed around. So we act like a product team: site teams are customers, the core has a roadmap, breaking changes are managed like a vendor would, and the contract’s test suite is the guarantee shipped with every release. Adoption has to be earned — by making the shared path genuinely less work than the forked one.
What this changes for you
On a site team? Stop maintaining an admin. Write the connector for your database, declare your extensions, and the rest — lists, editor, media library, publishing — is already there and improving without you.
Weighing the strategy? The bet is that our common ground is much larger than our differences — articles today; tags, categories, people and media tomorrow — and that a contract plus extension points can hold that line where copy-paste never could.
Just joined? Now you know where the admins are headed.
Where this stands today
Let’s be clear about the status: this is research, and a working proof of concept — not a production product yet. The contract exists, the shared admin runs, connectors and modules are real code you can try. What’s being proven now is the approach itself.
And the timing isn’t random. Three things make this the right bet now:
Spain is the first real test. We want to bring the Spanish websites into this back-office. That’s the hard version of the problem — different brands, different stacks, different editorial habits — and exactly why the admin has to be highly customizable rather than one-size-fits-all. The module system isn’t a nice-to-have; it’s what makes an integration like this possible without forking.
AI features belong in a shared admin. Assisted writing, tagging, translation, summaries — every brand wants them, and nobody should build them five times. A shared admin means AI features are built once and land everywhere. The contract helps here too: AI acts on content through the same explicit actions as a human editor — structured, revisioned, never a blind write.
AI coding agents changed the cost of connectors. The historical objection to “one admin, many backends” was the price of writing all those adapters. Tools like Claude Code and Codex flip that: a connector is exactly the kind of well-specified translation code an agent writes well — and the contract gives it a precise target, with the conformance suite as the automatic judge. The expensive part of this architecture just became the cheap part.
The stack, briefly
For the curious, what the shared admin is actually made of:
- TypeScript everywhere. The contract is a set of TypeScript interfaces — the same types the UI, the connectors, and the test suite all compile against. If your connector doesn’t match the contract, it doesn’t build.
- React, as a modern SPA-style app on TanStack Start: file-based routing, first-class data loading, server-side rendering. The article body editor is fully React too — rich text on Tiptap, drag-and-drop galleries, and custom module blocks rendered alongside the built-in ones.
- A pnpm monorepo: the contract, the UI core, the connectors and the example modules are separate packages with an enforced dependency rule — the UI depends on the contract only, never on a connector.
- Vitest for the conformance suite — the tests that ship with the contract and gate every connector.
- An in-memory fake connector for development: the full admin runs on your laptop with zero backend, seeded with fixtures. It passes the same conformance suite as the real ones — it is the reference implementation.
Nothing exotic — a deliberately boring, hireable stack. The novelty is in the architecture, not the tools.
Appendix: the article contract, at a glance
Simplified, but this is the real shape of the agreement — what an article is, the only ways to act on it, and what the admin tells you when something happens:
Article — what it IS
├─ id + revision ← every write carries the revision it
│ expects; stale writes are rejected
├─ title, slug, authors
├─ body: a list of blocks ← rich text, media, gallery, embeds…
│ unknown block types pass through
│ untouched
├─ tags, categories
├─ status: draft | pending | published | scheduled | archived | offline
│ ← computed from the article's state,
│ never stored or set directly
└─ dates: created, published, scheduled…
Article — what you can DO (the only write operations)
├─ create a new draft
├─ save the current draft
├─ publish now, or at a date (= schedule)
├─ unschedule cancel a scheduled publication
├─ take offline hide a published article
└─ archive soft removal — nothing is ever hard-deleted
Every action returns either the updated article or a list of user errors —
validation problems an editor can read and fix, not a stack trace.
Article — what it TELLS you (emitted events)
├─ created · saved · published · scheduled · taken offline · archived
│ ← one event per successful action
└─ each event carries who did it, to which article, and when
No generic “update anything” operation, no bulk writes, no hard delete. A connector implements exactly this — nothing more — and the conformance suite checks every line of it.
The events close the loop. Every brand already has publish machinery — CDN purge, sitemap rebuild, newsletter, push notifications. The shared admin knows none of it, and doesn’t need to: it emits “article published”, and each site reacts in its own code. Like your database, your side-effects stay yours — they just get a standard trigger.
And notice that events are only worth reacting to because writes are explicit commands. A generic update system could only tell you “something changed on row 4212”. Here the admin can say “this article was published, by this editor, at this time” — a fact your platform can act on with confidence. Commands and events justify each other; that’s why both are in the contract.
The POC in action
Not a mockup — the shared admin running today against the first connector, browsing a real catalogue of 320,000+ articles:

And the edit view — explicit statuses, revision shown next to the title, publish actions on the right, taxonomy and attribution as structured fields:

The body is the block editor — the article as a list of blocks. Here a gallery block with its media, cover choice and drag-to-reorder, followed by a rich-text paragraph. Custom module blocks render right alongside these:

And the media picker behind “Ajouter depuis la médiathèque” — each tab is a media source wired through the contract (the site’s library, per-article media, an external agency), searched live:

The details — the contract, how to write a connector, the extension
surface — live in the project docs and RFCs in the admin-intl workspace.
This article is the compass; the docs are the map.



