tinacms

Git-backed headless CMS that gives React apps live, in-context Markdown editing and a generated GraphQL content API.

Framework
npm
v3.12.1
13,780stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
92/100Excellent
Development Activity100
Maintenance100
Community68
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
83/100Excellent
Architecture85
Code Quality82
Innovation78
Learning Curve85

TinaCMS is an open-source, Git-native headless CMS. Content lives as Markdown, MDX, JSON, or YAML files directly in your own GitHub repository — there’s no external content database — and a GraphQL API is generated from your schema so pages can query it like post.author.firstName.

What sets it apart is its live, in-context visual editing: the useTina() hook and TinaCMSProvider2 component swap in editable data only when a page is loaded inside Tina’s admin, so editors click directly on the rendered page to change copy, and every save lands as a normal Git commit. It ships as a full self-hosted admin UI or can be paired with TinaCloud for hosted auth and media.

What You Get

  • A GraphQL API auto-generated from your content schema, so Markdown/MDX/JSON/YAML front matter can be queried like post.author.firstName
  • A drop-in useTina() hook and TinaCMSProvider2 component that swap production data for live, editable data only when the page loads inside Tina’s admin
  • A full self-hosted or TinaCloud-backed admin UI at /admin, with a Plate.js rich-text editor, drag-and-drop array fields, and a branch-switcher plugin for Git-based editorial workflows
  • PKCE-based OAuth authentication against TinaCloud or a custom auth provider, plus a pluggable form/field/screen system inherited from @tinacms/toolkit

Common Use Cases

  • Adding an editable content layer to an existing Next.js, Astro, or Hugo static site without migrating content out of the Git repo
  • Letting non-technical editors visually edit Markdown/MDX pages in place, with changes committed back to GitHub
  • Building a documentation or marketing site where content authors need a GraphQL query layer over structured Markdown collections
  • Standing up a fully self-hosted CMS admin, with no TinaCloud dependency, for teams that must keep content infrastructure in-house

Under The Hood

Architecture The tinacms package sits atop the monorepo’s @tinacms/toolkit (packages/tinacms/src/toolkit), a plugin-based CMS engine for forms, fields, sidebar screens, and alerts, which the top-level TinaCMSProvider (src/tina-cms.tsx) wraps in a React context provider alongside an error boundary, an internal GraphQL client (src/internalClient), and a PKCE-based auth layer (src/auth) for TinaCloud or a self-hosted backend. Content queries flow through useTina() (src/react.tsx), which hashes the query/variables pair, attaches Tina’s metadata for the visual quick-edit overlay, and rehydrates returned data with edit hooks when the page runs inside Tina’s admin iframe. The admin surface (src/admin) is a separate React Router app (RouteMappingPlugin, TinaAdminApi) mounted at /admin, talking to the same GraphQL backend, so schema changes ripple from @tinacms/schema-tools validation through generated GraphQL types into both the editing UI and the public site’s data layer.

Tech Stack Written in TypeScript (strict mode disabled in the shared base.tsconfig.json) targeting ESNext with bundler-based module resolution, the package pairs a large React surface (Radix UI primitives, @ariakit/react, @dnd-kit for drag/drop reordering) with a Plate.js-based (@udecode/plate*) rich-text/MDX editor, its own GraphQL client (graphql, graphql-tag, @graphql-inspector/core), Zod/Yup for runtime schema validation, final-form for form state, and internal @tinacms/* workspace packages (schema-tools, mdx, search, bridge) built with Turborepo. Peer dependencies are limited to react/react-dom, and internal build tooling compiles multiple entry points (client, react, admin, rich-text) into separate dist bundles for tree-shaking.

Code Quality The package ships extensive Vitest coverage (dozens of test files, including react.test.tsx, auth/pkce.test.ts, and internalClient/index.test.ts) run under happy-dom with React Testing Library, testing the GraphQL client, PKCE auth flow, and caching layer directly rather than relying only on end-to-end coverage — which lives separately in the monorepo’s Playwright suites, run across a wide set of CI workflows covering per-framework kitchen-sink tests (Next.js, Astro, Hugo), CodeQL scanning, and dependency review. Linting/formatting is enforced with Biome across packages and examples, and a changesets-based release process gates merges on version-bump metadata; TypeScript strict mode is explicitly off, so type coverage is present but not maximally enforced.

API Design The public API centers on one hook, useTina(), and one provider, TinaCMSProvider2 (the default export), that let a site keep rendering static GraphQL-fetched data in production while transparently swapping in live, click-to-edit data when the page loads inside Tina’s admin — no separate editor mode to wire up by hand. Getting started is a single npx create-tina-app@latest scaffold, and schema types (Config, Collection, Template, TinaField) are re-exported from @tinacms/schema-tools, with deprecated aliases kept for backward compatibility rather than shipped as hard breaking changes.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search