The CMS object in Tina is a container for attaching and accessing Plugins and APIs. On its own, the CMS does very little; however, since it's the central integration point for everything that Tina does, it's extremely important!

Setting up the CMS Object

A project that uses Tina will start by setting up an instance of the CMS.

import { TinaCMS } from 'tinacms'

const cms = new TinaCMS()

The TinaCMS constructor receives an object that can be used to configure CMS behavior. See CMS Configuration for details.

The <TinaProvider> Component

The <TinaProvider> component should wrap your entire site. It provides the following:

  1. The user interface for interacting with Tina, and
  2. A Context for accessing the CMS object via the useCMS hook.

After instantiating the CMS object, pass it to the <TinaProvider> component via its cms prop.

import * as React from 'react'
import { TinaProvider, TinaCMS } from 'tinacms'
import MyApp from './my-app'

export default function App() {
  const cms = React.useMemo(() => new TinaCMS())
  return (
    <TinaProvider cms={cms}>
      <MyApp />

Alternatively, you can use the withTina higher-order component to wrap your site with the <TinaProvider> component. withTina will automatically instantiate the CMS object.

import { withTina } from 'tinacms'
import MyApp from './my-app'

export default withTina(MyApp)

withTina accepts a configuration object as a second argument that is passed to the TinaCMS constructor.

import { withTina } from 'tinacms'
import MyApp from './my-app'

export default withTina(MyApp, {
  sidebar: {
    hidden: process.env.NODE_ENV === 'production',

Accessing the CMS Object

The CMS object can be retrieved from context via the useCMS hook.

import * as React from 'react'
import { useCMS } from 'tinacms'

// <SomeComponent /> is assumed to be nested inside of a <Tina> component
export default function SomeComponent() {
  const cms = useCMS()

CMS Configuration

When instantiating the TinaCMS object, you can pass in a configuration object. This allows you to configure some options for the sidebar, and also allows you to configure Plugins and APIs declaratively.

interface TinaCMSConfig {
  plugins?: Plugin[]
  apis?: { [key: string]: any }
  sidebar?: {
    hidden?: boolean
    position?: SidebarPosition
    theme?: Theme

pluginsArray of plugins to be added to the CMS object.
apisObject containing APIs to be registered to the CMS
sidebarConfigures behavior of the sidebar
sidebar.hiddenRemoves the sidebar outright
sidebar.position'displace': sidebar pushes content to the side when open; 'overlay': sidebar overlaps content when open
sidebar.themeOverride certain sidebar styles

import { TinaCMS } from 'tinacms'

const cms = new TinaCMS({
  plugins: [
      __type: 'hello',
      name: 'hello-dj',
      user: 'DJ',
  apis: {
    hello: {
      sayHello: () => alert('Hello, world!'),
  sidebar: {
    hidden: process.env.NODE_ENV === 'production',
    position: 'displace',