webhouse.appwebhouse.appdocs

Your content as flat JSON files. Render it with any language, any framework, any runtime.

The big idea

@webhouse/cms stores content as flat JSON files. Not in a database. Not behind an API. Just files in a directory:

content/
  posts/
    hello-world.json
    hello-world-da.json
    my-second-post.json
  pages/
    about.json
    contact.json
  globals/
    site.json

Every language that can read a file can consume this content. PHP, Python, Ruby, Go, C#, Rust, Elixir, Haskell, Bash — they all speak JSON.

Why this matters

Most CMS platforms lock you in. Contentful requires their SDK. Sanity wants their GROQ queries. WordPress needs PHP + MySQL. Strapi runs its own Node server. If you want to switch stacks, you export, migrate, and pray.

With @webhouse/cms, your content is files in your git repository. No lock-in. No migration. No vendor dependency. If you want to replace @webhouse/cms tomorrow with a different admin UI, your content is already in a portable format.

What's TypeScript-specific

Only the admin layer:

  • cms.config.ts — the schema definition (TypeScript)
  • Admin UI (Next.js)
  • AI agents (TypeScript)
  • Optional @webhouse/cms Next.js helpers

That's it. Everything below the admin layer is framework-agnostic.

What's framework-agnostic

ComponentFormatConsumable by
ContentJSON filesAnything that reads files
MediaImage files in public/uploads/Any web server
SchemaExportable as JSON Schema (schema export →)Any JSON Schema library
SEOsitemap.xml, robots.txt, llms.txtStandards-compliant crawlers
MCPPublic read-only MCP serverAny AI agent

The content format

Every document follows the same structure:

json
{
  "slug": "hello-world",
  "status": "published",
  "locale": "en",
  "translationGroup": "uuid-shared-with-translations",
  "data": {
    "title": "Hello, World!",
    "content": "## Welcome\n\nThis is my first post.",
    "date": "2026-04-08",
    "tags": ["intro", "hello"]
  },
  "id": "unique-id",
  "_fieldMeta": {}
}

To filter published content, skip anything where status !== "published". To read only one language, filter by locale.

Reading content from any language

The pattern is always the same:

  1. List files in content/<collection>/
  2. Parse each JSON
  3. Filter where status === "published"
  4. Optionally filter by locale
  5. Sort / render as needed

See the framework-specific guides:

The admin stays the same

Regardless of which framework you use to render the site, the CMS admin UI is the same Next.js application. Editors log in, edit content, hit publish — and the JSON files update in your git repository.

What about building?

F126 (planned) will let CMS admin invoke ANY build command — php artisan build, hugo --minify, bundle exec jekyll build, python manage.py collectstatic — not just our native TypeScript pipeline. Today you can still trigger builds via git hooks, CI/CD, or your own scripts.

Schema export

Non-TypeScript runtimes can't execute cms.config.ts, so the CMS exports a JSON Schema document (webhouse-schema.json) that describes the content model in a language-agnostic way. Reader libraries use this file to introspect collections, generate types, and validate documents.

Generate it from the CMS admin UI (Site Settings → Schema export → Save to project root) or from the CLI:

bash
npx cms export-schema --out webhouse-schema.json

Read the full schema export guide →

Trade-offs

File-based content is not for everyone. Consider:

  • Scale — thousands of documents work fine. Millions do not. Use a database adapter if you need scale.
  • Concurrent writes — filesystem adapter is single-writer. If you need real-time multi-editor, use the Supabase adapter.
  • Search — no built-in full-text search. Use a separate search index (Algolia, Meilisearch, Typesense).

For 95% of content-driven sites, file-based content is faster, simpler, and safer than any database.

Next steps

  • Read Introduction for the overall architecture
  • Pick your framework from the consumer guides above
  • Look at the examples for working code
Tags:ArchitectureFrameworksFilesystem Adapter
Next
Schema Export — webhouse-schema.json
JSON API →Edit on GitHub →