Running Simorgh locally needs a Next.js app, Yarn, and a backend you do not have
The BBC's Open Source Web Application. Contributions welcome! Used on some of our biggest websites, e.g.
At a glance
- What is it?
- Simorgh is the BBC's open source React and Next.js codebase for World Service news sites in 41 languages. The install is three commands, but several page types depend on BBC internal APIs and secret environment variables that contributors outside the BBC cannot set.
- Who is it for?
- Simorgh is worth reading if you build multilingual news front ends, because it solves service routing, variant URLs and AMP output under one renderer, and it ships with Storybook, Cypress, Jest and Lighthouse scripts already wired. It is the wrong base for a new project that needs to run unassisted, since topic pages, some staff commands and remote feature toggles all depend on BBC systems you cannot reach.
- 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 received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One renderer for 41 World Service languages
Simorgh renders the BBC World Service News websites as a ReactJS application, and it also renders AMP versions of news article pages for both World Service and Public Service News. The BBC News Web Engineering teams maintain it, and the repository description states it runs on some of the BBC's largest websites, including a Pidgin homepage the project points at as its own homepage link.
The interesting engineering constraint is not the framework, it is the URL space. Every service is a first path segment, so home pages are addressed as /:service, and languages with variants carry the variant as a second segment. Article pages live at /news/articles/:id, where the id is the asset ID generated by the BBC Content Management System, and AMP is a suffix on the same id rather than a separate page.
That gives three route shapes you will meet immediately:
/persian/articles/c4vlle3q337o
/persian/articles/c4vlle3q337o.amp
/zhongwen/simpThe first example is an article page, the second adds AMP, and the third shows a home page whose service requires a language variant. World Service home pages explicitly do not support AMP, which is a reasonable trade and one you only discover by hitting the route.
The project ships its own documentation index covering coding standards, contributing guidelines, a code review guide, a GPG signing guide, recommended tools and troubleshooting, and it notes that further documentation sits alongside the code rather than in that top-level list.
Getting it running: nvm, Yarn, and ws-nextjs-app
The install path is short. Node comes first, using the version pinned in .nvmrc, which a version manager picks up automatically:
nvm useThen Yarn, installed through npm:
npm install --global yarnThen the repository itself:
git clone [email protected]:bbc/simorgh.git
cd simorgh
yarn installLocal development starts by pointing the app at a backend through one environment variable. BFF_PATH selects the instance the backend-for-frontend talks to, and for a local one the README gives:
# For a local instance of fabl
export BFF_PATH="http://localhost:3210/module/simorgh-bff"With that set, run the Next.js app from its own workspace directory:
cd ws-nextjs-app
yarn devThe app serves on http://localhost:7081, and /pidgin is the route to try first. Article pages can be exercised without any BBC account because two CMS test articles are available on the test environment and locally, at /news/articles/c6v11qzyv8po and /persian/articles/c4vlle3q337o, each with its .amp counterpart.
Where the wall is: secret env vars and internal-only APIs
Some local development commands used by BBC staff need environment variables that are deliberately not in the repository. Staff are pointed at a separate simorgh-infrastructure repository for setting them on a machine, and that guide requires access.
Topic pages are where this bites hardest. They rely on BBC internal APIs that are not publicly accessible, so a contributor without access sees this warning during development:
No BFF_PATH set as environment variable, you will not have access to topicsThe documented answer is to contact the team. That is the honest state of affairs: topic page work is effectively closed to outsiders, and anyone evaluating the project should treat it as an untestable area rather than a bug.
Feature toggles are the softer version of the same problem. In production, toggles are set remotely through BBC internal systems. Locally those values are not fetched remotely and instead come from config files under src/app/lib/config/toggles, so the same code path can behave differently in local development and in production. The toggles documentation covers both the local values and how to pull remote values locally.
The test surface is already wired up
A codebase this size usually arrives with a test story you have to reverse engineer. Simorgh has it in package.json scripts, and the entries are specific enough to be useful.
Linting runs over src, data and cypress with eslint across js, jsx, json, ts and tsx extensions. Unit tests run Jest under Node's experimental VM modules, and the local variant shards the run and ignores the puppeteer path:
yarn test:lint
yarn test:unitThe combined `test:local` script chains lint, a dependency check, unit tests, and then a race between starting the app and running `amp:validate`, which validates AMP HTML output through the project's own validator script. Dependency governance is its own concern here: there are `test:dependencies` and `dependencyFreshness` scripts, plus a `dependencyFreshnessTable.csv` and an `esmDependencyTable.csv` at the repository root, so stale or duplicated dependencies are tracked as a visible table rather than left to review.
End-to-end work uses Cypress, configured through cypress.config.ts, and there is a separate Puppeteer suite with its own jest config under the puppeteer directory. Storybook serves on port 9001 and its build script copies envConfig/local.env to .env first. There is also a lighthouse directory with a run script, which tells you performance budgets are part of the normal loop rather than a special project.
Yarn workspaces, not a single package
The package manifest shows why a pull request touches more than one folder. Simorgh is a Yarn workspaces monorepo with declared workspaces for ws-nextjs-app, ws-nextjs-app/utilities/getAgent, src/app/routes/utils/fetchDataFromBFF and src/app/routes/utils/fetchPageData.
Those last two names are the architecture in miniature. Data fetching is not a generic client; it is split into a BFF layer and a page-data layer, each its own workspace, which is exactly why BFF_PATH is the first thing the local setup asks you to set. The named utility getAgent suggests the HTTP agent used for upstream calls is isolated too, which is where per-service timeouts and headers would live.
The sideEffects list is also unusual and worth noting for anyone copying the config: it marks the moment-timezone include, psammead-locales, all cypress paths, and every scss and css file as having side effects. That is the correct annotation for a project where dropping unused styles would break rendering, and it is a small sign of how carefully the build is tuned.
How Simorgh differs from building a news site on a plain Next.js starter
Most teams reach for a news front end by taking a generic Next.js starter and adding routing, an image pipeline and a CMS client. Simorgh already solved that, but the solution comes with an institution attached.
The practical difference is route vocabulary. A generic starter gives you /posts/[slug]. Simorgh gives you a service segment, an optional variant segment, an asset id from the CMS in the path, and a parallel.amp rendering of the same asset. Adopting them wholesale brings a route scheme designed around BBC editorial services, not around your content model.
The second difference is AMP, which the project still renders and validates in its own test path. Most modern news rebuilds have dropped AMP; keeping it means keeping a second rendering target and the validator that guards it.
The cost is licence and governance. The repository licence is a custom one that GitHub cannot classify, which is unusual and means you must read the LICENSE file before reusing code. On top of that, the contribution path is formal: code of conduct, coding standards, a code review guide, and a GPG signing guide for commits.
Editorial conclusion
Simorgh is worth reading if you build multilingual news front ends, because it solves service routing, variant URLs and AMP output under one renderer, and it ships with Storybook, Cypress, Jest and Lighthouse scripts already wired. It is the wrong base for a new project that needs to run unassisted, since topic pages, some staff commands and remote feature toggles all depend on BBC systems you cannot reach. Before adopting anything from it, run yarn install, set BFF_PATH to a local instance and open http://localhost:7081/pidgin; if that route renders, the rest follows from the documented route patterns.
Frequently asked questions
How do I run Simorgh locally?
Install Node at the version in .nvmrc with `nvm use`, install Yarn with `npm install --global yarn`, clone the repository and run `yarn install`. Then export BFF_PATH and start the app with `cd ws-nextjs-app` followed by `yarn dev`, which serves on http://localhost:7081.
Why does Simorgh print "No BFF_PATH set as environment variable"?
Topic pages call BBC internal APIs that are not publicly accessible, so without BFF_PATH set you lose access to topics. A local instance can be pointed at with `export BFF_PATH="http://localhost:3210/module/simorgh-bff"`, and staff-only topic work needs access to the infrastructure repo for secret variables.
What URL do I use for a Simorgh article page?
Article pages are served at /news/articles/:id, where the id is the asset ID generated by the Content Management System. AMP pages add the .amp suffix, and languages with variants put the variant in the path, for example /zhongwen/articles/c3xd4x9prgyo/simp.
Can I test article pages in Simorgh without CMS access?
Yes. Two articles are available on the BBC test CMS and locally: /news/articles/c6v11qzyv8po and /persian/articles/c4vlle3q337o, each also served with the .amp suffix.
How does Simorgh handle feature toggles in local development?
In production the toggles are set remotely through BBC internal systems. Locally those values are not fetched remotely and come from config files under src/app/lib/config/toggles, so local and production behaviour can differ.
What licence is Simorgh released under?
It is not a standard OSI licence. The repository is listed as carrying a custom licence that GitHub cannot classify, so the LICENSE file in the repository is the thing to read before reusing the code.
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/bbc-simorgh)Was this useful?