Getting started

What is in the repository

Nine packages and an app, with a dependency direction that a script enforces rather than a document requesting.

The repository is an npm workspace with one app and nine packages.

PathWhat it is
apps/webThe Next.js reference frontend, the Studio mount and the API mount. No business logic.
packages/content-corePure domain. Draft semantics, patches, transactions, constraints, GROQ planning, the environment contract. No dependencies at all.
packages/content-storePostgres: documents, transactions, revisions, GROQ execution, realtime.
packages/content-authSupabase Auth, profiles, roles, grants, RLS identity.
packages/content-assetsBlob bytes, metadata, transform URLs.
packages/content-apiThe HTTP surface, as pure request-to-response functions.
packages/content-nextThe Next.js adapter. The only package that may import next.
packages/content-studioThe forked Sanity Studio.
packages/demo-studioThe example schema, desk structure, templates and demo content.
packages/cliinit and login.

The rule that keeps it honest

The dependency direction is checked by a script that reads every workspace manifest and every import statement. Four rules:

  1. content-core imports nothing but its own types.
  2. content-api never imports next, so it stays mountable outside Next.js.
  3. content-next is the only package that does.
  4. The Studio packages may not import a server package; they reach the backend over HTTP, exactly as a Studio would.

A new package with no entry in the rule table is itself a failure, which is what stops the graph drifting quietly.

Where the example content lives

packages/demo-studio/content/ holds the seeded dataset and its images. The prose in it is written as Markdown in content/source/ and compiled into the committed dataset.json, which is what the seeder reads and what the schema tests validate. Replacing the example with your own content model means changing that one package.