Try it in one command:
npx create-wordjs@latest my-siteNo PHP, no MySQL, no build step โ it downloads a ready-to-run bundle, starts a single process, and prints a one-time setup-wizard URL for you to open in your browser.
WordJS is free, open-source software for building and running a website โ a blog, a shop, a company site, a portfolio. If you've heard of WordPress, think "WordPress, rebuilt for today": you get a visual, drag-and-drop page builder, ready-made themes and plugins, and search-engine-friendly pages out of the box.
The difference is what happens when you install a plugin.
On most website software, every add-on you install gets the keys to everything โ your database, your passwords, your files. One bad or hacked plugin can quietly wreck the whole site. It's the single most common way websites get breached.
WordJS is built so that can't happen.
Think about apps on your phone. A flashlight app can't read your bank messages unless you let it โ each app is boxed off and has to ask permission for anything sensitive.
WordJS does that for website plugins. Every plugin runs in its own locked box (a separate, operating-system-enforced process) and starts with nothing โ no access to your files, your database, your visitors' data, or the internet. It only gets a capability when you, the admin, grant it โ and you see exactly what each plugin is asking for.
So a plugin that turns out to be buggy, greedy, or outright malicious stays in its box. It can't read your passwords, steal your config, or take the site down. That safety is enforced by the operating system itself โ not by trusting the plugin to behave.
Every other major CMS runs plugins with full trust. This is the one thing they can't copy without breaking their entire ecosystem โ and it's what WordJS is built around.
Building a page by dragging blocks and editing text right on the canvas โ the visual editor ships in the core, not as a paid add-on.
| WordJS | WordPress | Ghost | Strapi | Payload | |
|---|---|---|---|---|---|
| Plugins can't compromise the site | โ OS-enforced sandbox | โ full trust | โ no plugin runtime | โ in-process | โ in-process |
| You approve what each plugin can do | โ per-plugin, default-deny | โ | โ | โ | โ |
| Drag-and-drop page builder in core | โ built in | partial (paid builders) | โ | โ headless | โ headless |
| SEO-ready out of the box | โ SSR + metadata + sitemap | โ via plugins | โ | โ your job | โ your job |
| Import your WordPress site | โ built-in importer | โ | โ | โ | โ |
| What it takes to run | 1 process, SQLite | PHP + MySQL | Node + MySQL | Node + DB + frontend | Node + DB |
| License | MIT | GPLv2 | MIT | MIT (paid tier) | MIT (paid cloud) |
| Ecosystem maturity | 60k+ plugins | large | large | growing |
The honest row is the last one: WordJS is young, and every plugin and theme in its marketplace today is first-party โ there's no third-party author community yet. What it already has is the row at the top.
|
๐จ Build
|
๐งฉ Extend โ safely
|
โ๏ธ Run
|
See the full feature list
Plugin system & security (the core differentiator)
- OS-process plugin sandbox. Every plugin runs in a separate operating-system process (
child_process.fork) โ its own memory and event loop โ so a crash, memory blow-up, or exploit is contained by the kernel and never takes down the host. Plugins reach the core only through a permission-checkedwordjsbridge (structured-clone RPC, no live host references, an exact method allow-list). - Install-time code scanner. Before a plugin can activate, its JavaScript is parsed and walked for dangerous constructs (
eval,exec/spawn, dynamicrequire, sensitive modules, forbiddenprocessaccess). It's fail-closed (an unparseable file is rejected) and runs on every plugin โ no exemptions. - Ask-permission model (default-deny). A plugin's manifest requests scoped capabilities (
database,filesystem,settings,users:read,email:provider,notifications:provider,network, โฆ); an admin grants each one per plugin. A call works only if the capability is BOTH declared AND granted. Activation shows the admin exactly what the plugin requests and grants that declared set โ only when the plugin has no grant record yet, so a later per-permission revoke survives a re-activation. First-party plugins get no extra privilege โ same sandbox, same rules. - Kernel hardening on Linux (default-on). Each plugin child also runs as an unprivileged user with dropped capabilities,
no-new-privs, PID/IPC/UTS namespaces, a read-only filesystem, and aseccompsyscall denylist. A plugin without thenetworkgrant is dropped into an empty network namespace, so it can't reach the internet or your internal services even at the kernel level. (Probe-gated, with a clean fallback where unavailable; Windows gets a Job Object memory cap; macOS relies on process isolation.) - Per-plugin data isolation. Each plugin gets only its own
wjp_<slug>_database tables and a secret-scrubbed view of config โ coreusers/options/sessionsand secrets are unreachable. On PostgreSQL/MySQL the database itself enforces this via a per-plugin low-privilege role/user. - Plugin & theme marketplace. A curated catalog of 31 first-party plugins and 64 first-party themes with one-click, sha256-verified installs through the same hardened, sandboxed pipeline as manual uploads. Sources are admin-configurable (point it at any HTTPS catalog); all catalog items are first-party today, with third-party submissions on the roadmap.
Authoring & content
- Visual builder (Puck) โ drag-and-drop editing, in-place rich text (bold/italic/links, a color picker with eyedropper, font family from your installed fonts, size, alignment), a searchable block inserter with reusable section patterns, and a device preview (desktop/tablet/mobile) that renders the canvas at true device width.
- Real server-side rendering โ public pages are React Server Components, so crawlers and first paint get the real content, per-page metadata (
generateMetadata), OpenGraph/Twitter cards, JSON-LD, real404s, and a no-JS search form. - SEO basics โ semantic HTML,
sitemap.xml,robots.txt, and an RSS feed. - Themes โ a shared, token-driven CSS framework (
--wjs-*design tokens) that auto-styles pages, plus a live customizer at/admin/themes/customize. A theme's optional server-sidefunctions.jsruns in the same sandbox as plugins. - Hooks, filters & shortcodes (WordPress-style), dynamic roles & permissions (database-driven), and UI in espaรฑol / english / portuguรชs.
- WordPress (WXR) importer โ upload a
.xmlexport to bring over authors, categories/tags, posts/pages (with meta, term relationships, and threaded comments), preserving publish dates. Idempotent and re-runnable. - Backups โ full-site export/restore with retention pruning, plus privacy-first analytics (no cookies, daily-rotated salted IP hashing) and a built-in cron.
Operations
- Gateway โ a clustered reverse proxy (one worker per CPU, auto-respawn), health-check eviction, an mTLS internal control channel, and SSE-aware proxying. It also acts as the cluster CA for multi-machine deployments.
- Automatic TLS โ Let's Encrypt via HTTP-01 or DNS-01, manual upload, or a self-signed dev fallback; renewal works in single-process mode too.
- Databases โ SQLite (default), PostgreSQL, or MySQL 8+/MariaDB, all behind one interface with a migration system to move between them.
- Headless-friendly โ scoped API tokens (
Authorization: Bearer wjt_โฆ, per-resource scopes), HMAC-signed SSRF-safe webhooks, and token-gated Prometheus metrics. - Native mail server โ an optional, fully sandboxed first-party plugin: inbound SMTP, direct-MX delivery, and DKIM signing.
The same codebase runs three ways โ switch anytime, no data migration:
| Mode | What it is | Best for |
|---|---|---|
| ๐งฑ Monolith | Everything in one process, one port | The simplest deploy โ a small VM or container |
| ๐ Split (default) | Gateway + backend + frontend on one host | Scaling services independently |
| ๐ Separate | The three services on different machines, joined over mTLS | Larger, distributed setups |
# The whole thing, one process:
npx create-wordjs@latest my-site # then open the printed wizard URL
# Or, from a source checkout:
npm run install:all
npm run dev:mono # monolith on https://localhost:3000 (self-signed)
npm run dev # or the 3-service splitArchitecture & run-mode details
graph TD
User((User)) --> Gateway[Gateway :3000]
Gateway --> Frontend[Next.js Frontend :3001]
Gateway --> Backend[TypeScript Backend :4000]
Backend --> DB[(SQLite / PostgreSQL / MySQL)]
Backend --> Plugins{Isolated Plugins}
- Gateway โ clustered Node/Express reverse proxy: routing, load-balancing, health-check eviction, mTLS internal channel, SSE-aware proxying, and the cluster CA.
- Backend โ the core engine (content, users, roles, the plugin/theme system, mail, certificates, and the sandbox). TypeScript, compiled to JS for production.
- Frontend โ the public site and the Next.js admin, including the Puck visual builder.
Monolith runs the backend (with its isolated plugins) and the Next.js frontend in one process on :3000 โ no gateway proxy, no cluster โ while still handling TLS, security headers, compression, and SEO rewrites locally. Split runs them as three cooperating processes behind the gateway. Separate spreads those three across machines: create-wordjs gateway --host <ip> makes the first box the cluster CA and prints ready-to-paste join commands with single-use, role-bound tokens; each other box enrolls over mutual TLS with no cert hand-copying.
See the Separate-mode guide for the walkthrough.
| ๐๏ธ Architecture | ๐ ๏ธ Development & Build | โจ๏ธ CLI & Setup |
| ๐ Plugin Tutorial | ๐งฉ Plugins Reference | ๐งฑ Plugin Isolation |
| ๐จ Themes | ๐ฅ๏ธ Frontend | ๐ฐ๏ธ Gateway |
| ๐๏ธ Database | ๐๏ธ Plugin Database Access | โ๏ธ Mail Server |
| ๐ Deployment | ๐งฉ Separate Mode | ๐ Multi-Node Ops |
| ๐ฅ Import from WordPress | ๐ Notifications | ๐ก REST API |
| ๐ Security Policy | ๐ก๏ธ Security Architecture | ๐งญ Product Positioning |
Live API reference (Swagger/OpenAPI) is served at
http://localhost:4000/api/v1/docs(admin only).
Beta ยท pre-production ยท primarily solo-maintained.
WordJS recently completed rounds of security hardening (fixing a CSRF bypass, committed secrets, and XSS sinks, among others). The plugin sandbox has had multiple internal red-team passes โ but there is no independent third-party audit yet. An external audit is strongly recommended before any production or internet-facing deployment, and the residual risks are documented plainly in SECURITY.md and POSITIONING.md.
The whole ecosystem is first-party: the marketplace ships 31 plugins and 64 themes, but there's no third-party author community or public review pipeline yet. Use it to build, learn, and experiment โ do your own review before trusting it with real data or real users.
The plugin sandbox is designed to fail closed, with defense-in-depth layers (see What's inside and Security Architecture). Beyond plugins, WordJS ships TOTP two-factor auth with an admin-enforced MFA-by-role policy, JWT revocation, per-(IP + account) login throttling, constant-time secret comparison, origin-pinned CSRF protection, and SSRF-safe outgoing webhooks.
Before exposing WordJS to the internet: have it independently audited, rotate every secret, and set a strong gatewaySecret (the gateway refuses management endpoints while the default is in place). Found a vulnerability? Please follow the disclosure process in SECURITY.md.
Tech stack
- Runtime: Node.js (โฅ 20.9; Node 20/22 LTS recommended)
- Backend: TypeScript โ compiled with
tscfor production,ts-nodefor dev - Frontend: Next.js (React 19)
- Editor: Puck ยท Styling: vanilla CSS + Tailwind
- Communication: REST + JWT + scoped API tokens + WebSockets/SSE
- Gateway: Express + Node
cluster, http-proxy, mTLS internal channel - Sandbox:
child_processOS-process isolation +acorncode scanning + runtime require proxies + layered memory caps (cgroup / Windows Job Object / RSS-poll) - TLS:
acme-client(Let's Encrypt HTTP-01 / DNS-01) - Database: SQLite (
better-sqlite3/sql.js), PostgreSQL (pg), or MySQL/MariaDB (mysql2) - Tooling: ESLint + Prettier,
node:test, GitHub Actions CI
Run from source & backend scripts
npm run install:all # install root + sub-packages
npm run dev # split: gateway + backend + frontend
npm run dev:mono # or everything in one process, one portPublic site on port 3000, admin at /admin โ dev:mono self-signs a localhost certificate (https://localhost:3000; WORDJS_HTTP=1 for plain HTTP), and the split gateway switches to HTTPS once setup writes ssl.enabled. First-run setup (database + admin user) runs in the browser wizard, or via npm run setup.
In production the backend is compiled (tsc โ dist/) and run as plain JS. From backend/:
| Script | Purpose |
|---|---|
npm run build |
Compile to dist/ (strict config) |
npm run typecheck |
Strict type-check (tsc --noEmit), enforced in CI |
npm test |
Test suite (node --test) |
npm run lint / format |
ESLint / Prettier |
CI (.github/workflows/ci.yml, Node 22) runs the strict type-check, the compiled build, a dependency license gate, unit tests, integration tests against real postgres:16 + redis:7 containers, and the frontend lint/type-check/tests/build.
- ๐งฉ Third-party marketplace โ open the catalog to community authors, where "sandboxed & reviewed" is a verifiable trust badge.
- โ๏ธ Media CDN โ S3-compatible object storage.
- ๐ Multi-site โ manage multiple domains from one install.
- ๐ก๏ธ More kernel hardening โ building on the default-on Linux sandbox layer.
MIT โ see LICENSE. Third-party dependency notices are in THIRD-PARTY-NOTICES.md.
