Unlock seamless workflows and faster delivery with our latest releases – get the details

React Compiler and Sanity

Sanity Studio v3.65.0 introduced support for the React Compiler. The compiler improves performance by automatically optimizing component rendering. This reduces the amount of manual memoization developers have to do through APIs such as useMemo and useCallback.

If you use @sanity/pkg-utils and/or @sanity/plugin-kit to distribute custom plugins and tools on npm then it's also possible to use the compiler there.

Sanity Studio

Install the babel and ESLint plugins for the compiler

npm install --save-dev babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta

Setup your ESLint config to include the compiler

{
  "parser": "@typescript-eslint/parser",
  "plugins": ["react-hooks", "react-compiler"],
  "rules": {
    "react-compiler/react-compiler": "warn",
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "error"
  }
}

You don't need to fix all the warnings before you can start using the compiler, you can incrementally adopt it.

It's also recommended that you have strictNullChecks enabled.

React 18

Install the react-compiler-runtime package as a direct dependency

npm install react-compiler-runtime@beta

And add reactCompiler to your sanity.cli.ts configuration, and set target to '18'

import {defineCliConfig} from 'sanity/cli'

export default defineCliConfig({
   api: {
      projectId: 'abc123',
      dataset: 'production',
   },
   reactStrictMode: true,
   reactCompiler: {target: '18'},
})

React 19

And add reactCompiler to your sanity.cli.ts configuration, and set target to '19'

import {defineCliConfig} from 'sanity/cli'

export default defineCliConfig({
   api: {
      projectId: 'abc123',
      dataset: 'production',
   },
   reactStrictMode: true,
   reactCompiler: {target: '19'},
})

Since React 19 has the compiler runtime built in there's no need to install react-compiler-runtime.

Embedded Studios

If your studio is hosted inside something like a Next.js, Remix app or otherwise not using sanity build and sanity dev commands?

If so you'll have to enable the compiler through one of the methods documented here.

Publishing Sanity plugins and tools

Since the compiler needs to run on the original source code it's not possible for Sanity Studio's to compile the libraries they use. Instead, library authors need to ship compiled code to npm.

At Sanity we use @sanity/pkg-utils to build our libraries. It handles ESM, CJS, and even the React Compiler. Libraries like react-rx, @sanity/ui and @portabletext/editor, sanity, and @sanity/vision, are already shipping compiled code this way.

Start off by installing the ESLint and Babel plugins

npm install --save-dev --save-exact babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta

Your ESLint config should enable the compiler, as well as strict eslint-plugin-react-hooks rules

{
  "parser": "@typescript-eslint/parser",
  "plugins": ["react-hooks", "react-compiler"],
  "rules": {
    "react-compiler/react-compiler": "warn",
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "error"
  }
}

You don't need to fix all the warnings before you can start using the compiler, you can incrementally adopt it.

It's also recommended that you have strictNullChecks enabled.

You also need to install the react-compiler-runtime if you support react 18

npm install --save-exact react-compiler-runtime@beta

It's very important that the direct dependency you use, use an exact version number.

Next, you add two lines of code to your package.config.ts

import {defineConfig} from '@sanity/pkg-utils'

export default defineConfig({
  // ... other stuff
  babel: {reactCompiler: true},
  reactCompilerOptions: {target: '18'}, // matches the minimum `react` major your library requires
})

Troubleshooting

Follow the official troubleshooting docs in case you run into problems. In our experience it's incredibly rare for the compiler to create a regression, it typically choses to skip over optimizing components it deems unsafe, or too complex to safely memoize.

Should a rare problem occur it's often enough to add 'use no memo' at the top of the affected file, to buy you time and find the fix. And then use ESLint with eslint-plugin-react-compiler and eslint-plugin-react-hooks to find issues that could be the root cause. Running React Strict Mode is also incredibly helpful to uncover root issues.

Was this article helpful?