How Ghost built an open source publishing platform on Node.js
Ghost is an open source publishing platform run by a nonprofit foundation, used for blogs, newsletters and paid memberships. Its core is a Node.js JSON API with MySQL, a separate admin app now being rebuilt in React, and outside services like Stripe, Mailgun and Tinybird for payments, email and analytics.
Ghost is built as a RESTful JSON API, split into a Content API and an Admin API. The admin is a completely separate client of that API, so the editor stays fast without slowing down the public site, and writers never need Git to publish.
The public site comes from a theme layer served by Express, with Handlebars templates. Ghost says it picked the whole JavaScript approach so teams already used to JavaScript codebases would feel at home.
For years the admin ran on Ember. The move to React happened screen by screen, with new React apps running inside the old Ember admin. Today the admin app in the monorepo is a React project built with Vite, styled with Tailwind and tested with Vitest, and the contributor guide says all new admin features must be built in React.
The server is going through a similar cleanup. The stated top priority is type safety: moving the code from JavaScript to TypeScript, validating incoming data with Zod and slowly replacing the Bookshelf ORM with services, repositories and plain Knex.
Ghost 6.0: analytics and the social web as separate services
Until Ghost 6.0, released in August 2025, Ghost was a single app on a server with one MySQL database. Version 6 added native, cookie-free web analytics, built on ClickHouse through a partnership with Tinybird, and a connection to the open social web over ActivityPub.
Both features run as independent services next to Ghost. That is also why Docker Compose became an official way to install and run Ghost, and it is set to become the default in Ghost 7.0.
Ghost does not try to send bulk email itself. Newsletters go through Mailgun, the only supported bulk provider, because sending mass email over plain SMTP can get the server's IP blacklisted. Regular SMTP is still used for transactional messages like login links and invites.
Paid memberships run on Stripe: once a site connects its Stripe account, the prices created in Ghost Admin show up there automatically.