RealWorld's repository holds a spec, not a Medium clone, and only two backends are verified
GitHub describes it as "The mother of all demo apps" , Exemplary fullstack Medium.com clone powered by React, Angular, Node, Django, and many more. The repository metadata lists TypeScript as its primary language. The metadata lists the NOASSERTION license. This article stays within the project description and details documented in the GitHub repository README.
At a glance
- What is it?
- realworld-apps/realworld contains no application code. The top level is a spec directory, a documentation site, a shared CSS theme, and a Makefile whose only non-documentation targets convert a Hurl API spec into a Bruno collection. Over 100 implementations live in other repositories, two of which are described as passing the test suite, and the spec itself has no releases to pin them to.
- Who is it for?
- RealWorld suits someone building a frontend or backend and wanting a contract, a test suite, and a shared stylesheet to build against, and it is a fair way to compare two frameworks on the same application. It does not suit someone looking for a working Medium clone to fork, because there is no application in this repository, and it does not give you a versioned spec to pin to.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 35 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The repository contains a contract, not the Medium clone
The top level of the tree is .github/, .gitignore, CLAUDE.md, CONTRIBUTING.md, LICENSE, Makefile, README.md, assets/, docs/, and specs/. There is no application directory, no server, and no client.
The repository description calls it the mother of all demo apps and an exemplary fullstack Medium.com clone powered by React, Angular, Node, Django, and many more. That phrase describes a family, not a program. The README's own framing is that you can see how the exact same Medium.com clone is built using different frontends and backends, and that you can combine any frontend with any backend because they all adhere to the same API spec.
So the contract is here and the implementations are elsewhere. Over 100 of them have been created, and they are browsed on CodebaseShow rather than in this tree. If you arrived expecting a Medium clone to fork and extend, this is the wrong repository, and the fastest way to find what you actually want is the implementations index the README points at.
The spec is written in Hurl and the Bruno collection is generated from it
The Makefile has exactly two targets that are not about documentation, and both run the same script:
bruno-generate:
bun specs/api/hurl-to-bruno.js
bruno-check:
bun specs/api/hurl-to-bruno.js --checkThat is the whole build for the API contract. The canonical form lives in Hurl files under specs/api/, and a conversion script turns them into a Bruno collection for people who would rather click than read a text format.
The consequence is a generated artefact with a drift risk, and a guard that only runs when somebody runs it. The check mode is the mechanism that would catch the generated collection falling behind the spec, but nothing in the Makefile wires it into the other targets or into a build, so it is a target you have to remember. Anyone implementing against a stale Bruno collection is implementing a contract that is not the one in specs/api/, and the mismatch will look like a bug in their code.
Read the Hurl files. The Bruno output is a convenience for testing tools, and it is the copy that is allowed to lag.
The docs site is Astro on bun, and the clean target deletes three directories
The documentation targets all change into docs and hand off to bun:
documentation-setup:
cd docs && bun install
documentation-dev:
cd docs && bun run dev
documentation-dev-host:
cd docs && bun run dev --hostThere is also a build target, a preview target, and a clean target that runs rm -rf docs/.astro docs/dist docs/node_modules. The .astro directory is Astro's cache directory and dist is its build output, which is how you can tell the documentation site is an Astro project without opening its package file.
Two practical consequences. Bun is a hard requirement for working in this repository, since every documentation target calls it and there is no npm or yarn path in the Makefile. And the two dev targets differ by a single flag, --host, which is the difference between a dev server reachable from another machine and one bound to localhost. For anyone pairing a frontend and a backend on two machines, that flag is the setting that decides whether the pair can talk at all.
The hosted API isolates every account from every other account
The README offers a shared backend for public use at api.realworld.show, with no API keys required, demo accounts provided, and one clause that does the real work: real accounts can't see each other.
That isolation is what makes a shared instance safe to point a frontend at, since a stranger's posts are not visible to you. It is also what limits what you can test. Anything that depends on one user observing another user's data, a follow, a like, a subscription relationship, a duplicate-username conflict, is not exercisable on the hosted API at all. The instance is a conformance target and a demo, not a test fixture for multi-account behaviour.
The reference frontend compounds that. The demo at demo.realworld.show is described as an Angular frontend plugged to this backend, so the visual reference implementation is one framework's rendering of the spec. For a React or Vue implementation, that page is a target to match by API shape, not a template to copy, and the shared stylesheet is what the README offers for visual consistency instead.
Over 100 implementations, and two described as spec-compliant
Those two numbers appear on the same front page and they are not comparable. The Implementations section says over 100 implementations have been created using various languages, libraries, and frameworks, and sends you to CodebaseShow to browse them. Then a separate section titled Spec-compliant backends says these backends pass the full API spec test suite, and names exactly two: Nitro with Prisma and Zod in TypeScript, and Django Ninja in Python.
So the count of implementations and the count of verified ones differ by nearly two orders of magnitude. The README does not say what the other implementations are. They could be non-compliant, compliant but never run against the suite, or built against an older revision of the spec, and nothing on the page distinguishes those cases.
For a reader choosing what to pair with a frontend, the two named backends are the only ones with a test suite behind them. The rest are demonstrations that a stack can be pointed at this spec, which is a different and weaker claim from conformance. The WIP implementations live in a discussion category rather than in the tree, so the frontier of the ecosystem is also outside the repository.
Two shared assets make frontends comparable, and one of them makes them identical
The repository supplies a shared stylesheet, assets/theme/styles.css, described as provided to build frontend implementations with identical UI and UX. It also supplies a shared end-to-end suite under specs/e2e/ to validate frontend implementations.
These are the two mechanisms behind the project's central claim, that the same app is built in every framework, and they work on different axes. The stylesheet makes frontends look alike, the E2E suite makes them behave alike, and a framework comparison is only meaningful when both are adopted. Two frontends that share neither are not comparable, and the README is effectively saying that participation means using the shared theme.
That is worth naming plainly, because it is a constraint as much as an offer. A frontend that adopts the shared theme inherits a visual identity chosen by the maintainers, and a project with an existing design system will find the two in conflict. The bundled CSS is the same trade any reference implementation makes, and here it is bundled as a contract.
The spec ships no releases, so implementations pin to a commit
The repository has no GitHub releases. The last push is dated 2026-08-26, and the maintainers are named individually: one maintains the spec, the test suites, and the demo website, and the other is the creator of the Layr framework and of the CodebaseShow site that indexes the implementations.
With no tagged versions, an implementation that wants to say which revision of the spec it targets has to reference a commit. That is a weaker guarantee than a version number, because nothing prevents the spec from changing in a way that is not breaking under the project's own judgement and still moves the target under an implementation that has not been revalidated.
There is a second licensing wrinkle at the same level. The repository records its license as unasserted, which is GitHub saying it could not classify the file, even though a LICENSE file sits in the root. Separately, the README sends you to docs/non-included/LICENSES_LOGOS.md for framework logo licensing and attribution. So there are two licence questions, code and logos, and the one that catches people out is logos, since a README showing a dozen framework marks carries attribution obligations the code licence does not cover.
Editorial conclusion
RealWorld suits someone building a frontend or backend and wanting a contract, a test suite, and a shared stylesheet to build against, and it is a fair way to compare two frameworks on the same application. It does not suit someone looking for a working Medium clone to fork, because there is no application in this repository, and it does not give you a versioned spec to pin to. Before starting, read the spec in specs/api/ rather than the generated Bruno collection, plan for the demo API's account isolation if you need cross-user behaviour, and treat the two named spec-compliant backends as the only verified ones.
Frequently asked questions
Is the real world still active?
If you mean this project: the repository's last push is dated 2026-08-26, it is not archived, and it has no GitHub releases. Two maintainers are named on the front page, one responsible for the spec, the test suites, and the demo website, and the other for the Layr framework and the CodebaseShow site.
how to use real world
There is nothing to install from this repository, because it holds the API spec rather than an application. To see the contract in use, point a frontend at the hosted backend API at api.realworld.show, which needs no API keys and provides demo accounts, and compare it against the Angular reference frontend at demo.realworld.show.
What problem does the RealWorld spec solve?
The README argues that most todo demos give a cursory look at a framework and never convey what building a real application involves. RealWorld aims for a sweet spot between simplicity and breadth by shipping the same application spec for every framework, so implementations can be compared on the same work.
How do I create a new RealWorld implementation?
The front page links a starter guide and spec for creating a new implementation, and a separate link for viewing upcoming implementations as WIPs in the project's GitHub Discussions. Every tutorial is built against the same API spec so that frontends and backends stay modular.
Which RealWorld backends pass the test suite?
Two are named on the front page as passing the full API spec test suite: Nitro with Prisma and Zod in TypeScript, and Django Ninja in Python. The repository separately states that over 100 implementations exist across frameworks, and those are browsed on CodebaseShow.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/realworld-apps-realworld)