# ReactPress, a self-hosted publishing system for people who work in React

> ReactPress packages an admin editor, a headless API, a Next.js visitor site, plugins and a desktop writing app behind one CLI command, so a small team can publish without assembling a CMS, a frontend and deploy glue by hand. It runs on an embedded SQLite database with no Docker on the default path, and the public site stays yours to theme in React.

**fecommunity/reactpress** — 🔥 ReactPress - The publishing system for React developers.（面向 React 开发者的发布系统。）Demo：https://www.gaoredu.com

- Repository: https://github.com/fecommunity/reactpress
- Website: https://docs.gaoredu.com
- Stars: 721 · Forks: 53
- Language: TypeScript
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/fecommunity-reactpress

## One CLI command replaces the CMS plus frontend plus glue

The pitch is in the project's own framing: a real editor for writers, a Next.js site you control, one install rather than WordPress or five tools glued together. The comparison table makes the argument concretely, listing who publishes, who owns the public site, time to a working site and offline writing for ReactPress against WordPress, Ghost, Strapi and Payload, and Hugo and Astro. ReactPress's rows say writers publish in an admin, you own the public site because it is Next.js, a working site takes one CLI command, and offline writing works through a desktop app. The documentation is direct about who this is for: independent developers who want a blog, notes or docs site they own, small teams where one person writes in the admin and another owns the public site, WordPress leavers who want the same habit without a PHP theme stack, and static site users who are tired of asking non-developers to open a Git repository.

## Getting a running site in three commands

The quickstart is the shortest part of the documentation:

```bash
npm i -g @fecommunity/reactpress
mkdir my-site && cd my-site
reactpress init
```

After that you open the site at http://localhost:3001 and the admin at http://localhost:3001/admin/ with the credentials admin and admin. Node 20 or newer is required, and the documentation states there is no Docker and no extra database on the default path. When something does go wrong there is a diagnostic command, reactpress doctor, which reads like a deliberate choice to make a failed install a recoverable situation rather than a debugging session. The desktop app is presented as the offline answer to the same problem, with the caption that you write offline and sync when you are back, which is the feature a Hugo user would miss most when a static site forces every edit through a text editor and a commit.

## The monorepo split: cli, server, web, themes, plugins, toolkit

The top-level entries describe the architecture better than any summary could. There is a cli/ directory holding the binary entry, a server/ directory for the API, a web/ directory for the admin, themes/ for the visitor site, plugins/ for extensions, a toolkit/ package, and desktop/ for the native writing app, with a pnpm workspace tying them together. The root package.json is private and declares pnpm@9.15.9 as its package manager, and it exposes a single bin, reactpress, pointing at cli/bin/reactpress.js. Many scripts in that file go through the same entry point with different flags, so dev, init and the docker subcommands are one program with arguments; a few, such as dev:docs and build:toolkit, call pnpm run in a subdirectory instead. A dev:web:local variant and a dev:api and dev:client split show that the admin, the API and the visitor site can each be run on its own, which matters when you are debugging a rendering problem and do not want to restart everything.

## Embedded SQLite by default, MySQL and Docker when you outgrow it

The environment template makes the default path explicit. The database section sets DB_TYPE=sqlite with DB_DATABASE pointing at .reactpress/reactpress.db, and the comment explains the switch: for MySQL through Docker you use reactpress init or embedded-docker along with DB_HOST, DB_PORT, DB_USER and DB_PASSWD instead. The API server is a NestJS service on SERVER_PORT=3002, with SERVER_SITE_URL required in production because a missing value previously produced an undefined prefix on media URLs. The visitor theme runs on CLIENT_SITE_URL at port 3001, uploads go to REACTPRESS_UPLOAD_DIR, and the bootstrap admin credentials come from ADMIN_USER and ADMIN_PASSWD on first start only. The comment on the first-run line matters for anyone deploying this: change them after the first login.

## Where the boundaries sit: a plugin system and a theme you still own

Two directories define what you extend yourself. The themes/ directory holds the public site, and a theme starter is published separately as reactpress-theme-starter with a live demo, so swapping the public theme is a supported path rather than a fork. The plugins/ directory is the extension point, and the documentation describes it as extending without forking, which is the phrase that matters: the design intent is that custom behaviour lives in a plugin you can update rather than in edits to the core that you have to rebase every release. The counterweight is that both surfaces are young. There is no catalogue of ready-made plugins in the documentation, no version compatibility matrix, and no plugin marketplace mentioned, so a team that expects to install a comments plugin, an analytics plugin and an SEO plugin on day one will be writing them. The visitor site demo does show search, comments and a knowledge base, so the theme starter demonstrates more than a bare blog.

## Deployment, Docker and the scripts that sit behind the CLI

Hosting is documented at docs.gaoredu.com, and the repository carries three compose files: docker-compose.dev.yml, docker-compose.prod.yml and docker-compose.prod.low-mem.yml, the last named for machines where memory is the constraint. The CLI wraps that lifecycle rather than asking you to memorise compose commands, with scripts for docker start, docker down, docker restart, docker status and docker logs, and a pm2:api script for running the API under a process manager. Build and deploy are shell scripts, build and deploy, invoked as sh scripts/build.sh and sh scripts/deploy.sh, and there is a separate build:api that builds the toolkit and the server in order. A vercel.json sits at the root alongside a scripts/ directory with dev-themes.mjs and a seed-legacy-media.mjs migration script, and an .env.example at the root carries a header comment explaining that reactpress init usually generates it and that secrets belong only in .env.

## Where ReactPress is the wrong tool

The clearest wrong case is a large editorial operation. The architecture is a single Next.js visitor site plus a single admin, which suits a small team, but it does not describe a multi-site network, a syndication workflow, a translation desk or a newsroom with a dozen desk editors and a rigid approval chain. The second limit is the plugin and theme story, already noted, and the third is that the admin is a web application, so the offline writing story leans on the desktop app rather than on the admin itself. The fourth is deployment responsibility. You own the Next.js site, which is the point of the product, and it also means build steps, host configuration, upgrades and the CMS and site version compatibility are yours to manage. A team that wanted a hosted multi-tenant product with a vendor handling backups and upgrades is looking for something else. The last point is version maturity: the newest tagged release is v4.0.0 from 2026-08-09, with a v4.0.0-beta.18 tag from 2026-07-12 before it, and the last push was on 2026-10-20, so trunk has moved past the published major version.

## Licence, package layout and the Chinese documentation

The project is MIT licensed with the licence file at the root, and it publishes a CHANGELOG.md, a CONTRIBUTING.md, a SECURITY.md and a CODE_OF_CONDUCT.md, which is a fuller governance set than most projects of this size carry. The published npm package is scoped, @fecommunity/reactpress, while the root package.json is named reactpress and marked private, so the CLI is the distributed artifact and the monorepo is the source. The documentation site is at docs.gaoredu.com with a Docusaurus setup that the package scripts build separately, and the env template carries optional Algolia keys for the docs search along with a DOCS_SITE_URL override. There are two READMEs, an English one and README-zh_CN.md, and the demo instance and the documentation site both sit under the gaoredu.com domain, so the audience this is built for is clear from the project structure alone.

## Conclusion

Adopt ReactPress when a small team needs writers to have a real admin interface while the public site stays a Next.js application you control, and when an embedded SQLite database is enough to start. Do not adopt it for a large editorial organisation with a separate design team, for a headless backend that must scale independently of the site, or if you need a mature plugin ecosystem on day one, because the plugin and theme surfaces are the parts you will build yourself. Verify first that Node 20 or newer is available, that the theme you want to swap in is React rather than PHP, and which of the deployment paths in the docs matches the host you have. The last push was on 2026-10-20 and the newest tagged release is v4.0.0 from 2026-08-09, so the trunk is moving ahead of the published version.

## FAQ

### How do I install and start a ReactPress site?

Install the CLI with npm i -g @fecommunity/reactpress, create a directory and run reactpress init. The site is then at http://localhost:3001 and the admin at http://localhost:3001/admin/ with the credentials admin and admin. Node 20 or newer is required.

### Does ReactPress need Docker or a separate database?

Not on the default path. The env template sets DB_TYPE=sqlite with the database file at .reactpress/reactpress.db, and the documentation states no Docker and no extra database is needed. For MySQL you use reactpress init or embedded-docker with the DB_HOST, DB_PORT, DB_USER and DB_PASSWD values.

### What does reactpress doctor do?

The documentation names it as the thing to run when something fails, alongside the statement that the default path needs no Docker and no extra database. It is presented as the diagnostic step for a failed install.

### Can I write posts offline with ReactPress?

The comparison table lists offline writing as a desktop app, and the repository carries a desktop/ directory with its own documentation. The stated behaviour is that you write offline and sync when you are back.

### How do I change the public theme without forking ReactPress?

The visitor site lives in the themes/ directory, and a separate theme starter is published as reactpress-theme-starter with a live demo. Plugins are the extension mechanism for adding behaviour, and the documentation describes this as extending without forking.

## Sources

- [fecommunity/reactpress on GitHub](https://github.com/fecommunity/reactpress)
- [License: MIT](https://github.com/fecommunity/reactpress/blob/master/LICENSE)
- [Project website](https://docs.gaoredu.com)
- [README](https://github.com/fecommunity/reactpress/blob/master/README.md)
- [Releases](https://github.com/fecommunity/reactpress/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/fecommunity-reactpress
