Define your schema. Fill it with content. Get a REST API, GraphQL API, and real-time WebSocket events — in under 10 minutes. Self-hosted. MIT licensed. Yours forever.
{ "id": 1, "slug": "hello-world", "status": "published", "locale": "en", "data": { "title": "Hello World", "body": "<p>My first post.</p>", "author": "Karthik" }, "createdAt": "2026-04-20T10:00:00Z" }
No config files. No plugins to install. No paid tier to unlock basic features.
Go to Content Types → New. Give it a name like blog and add fields: title (text), body (richtext), author (text). NodePress normalizes names to snake_case automatically.
Go to Entries → blog → New Entry. Fill in the fields. A URL slug is auto-generated from the title. Set status to Published when ready.
Your content is immediately available at your API endpoints or via GraphQL:
Built by a developer who got frustrated wiring together five different services.
Every content type gets instant REST endpoints AND a full GraphQL API with queries and mutations. No extra configuration. Swagger UI at /api/docs. Apollo Sandbox at /graphql.
Socket.io gateway broadcasts entry:created, entry:updated, media:uploaded and more. Subscribe to specific content type rooms. Redis adapter for multi-instance sync. Authenticated — JWT or API key required.
Build forms in the UI, embed them anywhere. Submissions trigger email or webhook actions. Three-layer spam protection: rate limiting, honeypot field, and Captcha (Turnstile / hCaptcha / reCAPTCHA).
Every entry has a locale field. ?populate=author,author.company resolves relation chains up to 3 levels deep in one batched DB query. ?fields=title,body for projection. ?search=keyword with PostgreSQL GIN full-text index.
Every entry save creates a version snapshot. Restore any previous state in one click. Schedule publishing with publishAt — a cron job auto-publishes on the minute. PostgreSQL advisory locks prevent duplicate runs at scale.
docker-compose.prod.yml starts Postgres + PgBouncer + Redis + NestJS + Next.js + Nginx + Prometheus + Grafana + automated daily backups. Memory limits, health checks, and graceful shutdown all configured.
Use REST for simplicity. Use GraphQL when you need to fetch multiple resources in one round-trip.
# List published blog postsGET /api/blog?locale=en&page=1&limit=10# Single postGET /api/blog/hello-world# With relations populatedGET /api/blog/hello-world?populate=author,tags# Create (with API key)POST /api/blogX-API-Key: np_your_key_hereContent-Type: application/json{"slug": "new-post","data": { "title": "New Post" }}
# List posts — query exactly what you needquery BlogPosts {entries(contentTypeId: 1, status: "published") {totaldata {idslugdatacreatedAt}}}# Create (requires JWT or API key)mutation CreatePost {createEntry(contentTypeId: 1slug: "new-post"locale: "en"status: "draft"data: "{\"title\":\"New Post\"}") {id slug status}}
Apollo Sandbox available at /graphql in all environments. Get your Bearer token from POST /api/auth/login.
No polling. No refresh. Content changes in NodePress — your UI updates immediately.
import { io } from 'socket.io-client';const socket = io('https://your-api.com', {path: '/api/realtime',auth: { token: 'Bearer eyJhbGci...' },});// Subscribe to a content type roomsocket.emit('subscribe', { contentType: 'blog' });// React to live changessocket.on('entry:created', ({ slug, contentType }) => {console.log(`New ${contentType}: ${slug}`);refreshFeed();});socket.on('entry:updated', ({ slug, status }) => {if (status === 'published') updateCard(slug);});
Honest comparison. No marketing spin.
| Feature | NodePressYou | Strapi v5 | Contentful | Sanity |
|---|---|---|---|---|
| Self-hosted | ||||
| Open source (MIT) | ||||
| Setup time | ~10 min | ~30 min | 5 min | 20 min |
| Docker required in dev | No | Yes | N/A | N/A |
| REST API | ||||
| Full GraphQL mutations | ||||
| Real-time WebSocket | Free | Paid | ||
| Multi-locale (i18n) | Free | Paid | ||
| Form builder | Built-in | |||
| Scheduled publishing | Free | Paid | ||
| Webhooks with retry | Basic | |||
| Audit log | Free | Paid | ||
| Preview tokens | ||||
| E2E test coverage | 173 tests | Partial | N/A | N/A |
| Production Docker stack | Complete | Partial | N/A | N/A |
Data current as of April 2026. We aim to be fair — if something's wrong, open an issue.
TypeScript end-to-end. Backend and frontend share zero runtime type coupling — both compile clean independently.
Every layer has a single responsibility. Easy to understand, easy to extend.
In production, Nginx sits in front of everything. /api/realtime gets dedicated WebSocket headers. /api/metrics is blocked from the internet and scraped by Prometheus internally.
Requires a server. ~$5/month on DigitalOcean or Hetzner.
We'll email you when it's ready.
Set up in 10 minutes. No credit card. No vendor lock-in.