TinaCMS is an open-source headless CMS with visual editing. This monorepo contains the core packages, CLI, admin app, and framework example apps.
This repo has a public security policy at SECURITY.md. Read it before touching code that could surface a vulnerability (auth, media routes, path handling, GraphQL resolvers, anything that accepts untrusted input).
Hard rules:
- Never file security vulnerabilities as public GitHub issues. Reports go to
security@tina.io, or as a draft GitHub Security Advisory. Public issues are explicitly forbidden bySECURITY.md, regardless of severity. - Never put bug specifics in test comments, PR descriptions, or commit messages. That's public disclosure by a different name. If a test guards against a known-broken behaviour, use neutral wording (e.g. "Pending upstream fix reported privately per SECURITY.md") and keep the internals — error messages, stack traces, affected function names, response-body specifics — out of the comment.
- Don't commit, push, or draft a public issue if you find a potential vulnerability. Stop, tell the user what you found and where, and let them decide the disclosure path (email, draft advisory, or public if they judge it's truly benign).
Scope of the above rules: every surface an agent might modify — source files, test files, inline comments, commit messages, PR descriptions, linked issue drafts, README snippets.
When writing regression tests that guard against a quietly-reported finding, mark the specific case with test.fixme (Playwright) or the framework equivalent, use a generic "pending upstream fix" message, and put the detail in a private channel only.
packages/ # Core packages (tinacms, tinacms-authjs, create-tina-app, etc.)
packages/@tinacms/ # Scoped packages (cli, app, datalayer, graphql, mdx, scripts, etc.)
examples/ # Framework example apps
next/kitchen-sink/ # Next.js 15 — the reference kitchen-sink implementation
next/tina-self-hosted-demo/ # Self-hosted with auth
astro/kitchen-sink/ # Astro 5 — mirrors Next.js kitchen-sink
hugo/kitchen-sink/ # Hugo kitchen-sink
react/kitchen-sink/ # React kitchen-sink
shared/ # Shared content and public assets across kitchen-sink examples
playwright/ # Playwright test infrastructure
scripts/ # Repo maintenance scripts
tests/ # Build verification tests
- Install:
pnpm install(from repo root) - Build core packages:
pnpm build(runsturbo run build --filter="./packages/**") - Watch mode:
pnpm dev(builds then watches via@tinacms/scripts) - Test:
pnpm test(runsturbo run test --filter="./packages/**") - Example apps: Each has its own
dev,build,build:localscripts — check the example'spackage.json
pnpm-workspace.yamldefines workspace packages and acatalog:section for shared dependency versions- Example apps use
workspace:*to reference local TinaCMS packages turbo.jsondefines build/test/types task dependencies
- Linting/Formatting: Biome (
biome.jsonat root). Example apps extend with"extends": ["../../../biome.json"] - TypeScript: Base config at
base.tsconfig.json. Examples extend it. Strict mode enabled. - Package manager: pnpm only. Never use npm or yarn.
CLAUDE.mdfiles are git symlinks to the siblingAGENTS.md. On Windows without Developer Mode, ifgit statusshowsTTtypechanges on them, rungit config --local core.symlinks false— git then materialises them as regular pointer files. Linux/macOS clones get real symlinks automatically.
All kitchen-sink examples implement the same content model to demonstrate identical functionality across frameworks. examples/next/kitchen-sink/ is the reference implementation.
| Collection | Format | Content Path | Collection File |
|---|---|---|---|
| Tag | JSON | content/tags/ |
tina/collections/tag.ts |
| Author | MD | content/authors/ |
tina/collections/author.tsx |
| Post | MDX | content/posts/ |
tina/collections/post.tsx |
| Blog | MDX | content/blogs/ |
tina/collections/blog.tsx |
| Page | MDX | content/pages/ |
tina/collections/page.tsx |
| Global | JSON | content/global/ |
tina/collections/global.ts |
Note: .tsx collection files contain JSX for custom field components (e.g., ColorPickerInput in global.ts theme field). .ts files are pure schema definitions. This applies across all kitchen-sink examples.
- TinaCMS wraps the framework dev server:
tinacms dev -c "<framework dev>" - Build order:
tinacms build && <framework build> - Content lives in
content/with identical MDX/JSON files across examples - Tina config at
tina/config.tsxwith collections intina/collections/ - Admin UI output to
public/admin/ - Media root:
uploads/withinpublic/
| Tool | Choice |
|---|---|
| Package Manager | pnpm (workspace-native) |
| Linting/Formatting | Biome (extends root config) |
| Styling | Tailwind CSS 4 (CSS-first config) |
| TypeScript | 5.7+ strict (extends base.tsconfig.json) |