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.
| Path | What it is |
|---|---|
apps/web | The Next.js reference frontend, the Studio mount and the API mount. No business logic. |
packages/content-core | Pure domain. Draft semantics, patches, transactions, constraints, GROQ planning, the environment contract. No dependencies at all. |
packages/content-store | Postgres: documents, transactions, revisions, GROQ execution, realtime. |
packages/content-auth | Supabase Auth, profiles, roles, grants, RLS identity. |
packages/content-assets | Blob bytes, metadata, transform URLs. |
packages/content-api | The HTTP surface, as pure request-to-response functions. |
packages/content-next | The Next.js adapter. The only package that may import next. |
packages/content-studio | The forked Sanity Studio. |
packages/demo-studio | The example schema, desk structure, templates and demo content. |
packages/cli | init 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:
content-coreimports nothing but its own types.content-apinever importsnext, so it stays mountable outside Next.js.content-nextis the only package that does.- 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.
