React Live Playground
React Live is a versatile library for creating interactive, live-editable React code playgrounds within web applications. It allows developers to render React components dynamically, display their editable source code, and provide a real-time preview of the changes. The current stable version is 4.1.8, with patch releases occurring frequently to address fixes and minor improvements, as seen in recent version bumps (e.g., 4.1.0 to 4.1.8). Key differentiators include its modular structure, allowing for flexible styling and composition of its core components (`LiveProvider`, `LiveEditor`, `LiveError`, `LivePreview`), and its focus on being production-ready. It abstracts the complexities of code compilation and error handling, making it suitable for documentation sites, component libraries, and interactive learning platforms.
Common errors
-
ReferenceError: React is not defined
cause The `scope` prop of `LiveProvider` did not include the `React` object, which is necessary for the transpiled code to function.fixPass `React` into the `scope` prop: `<LiveProvider code={code} scope={{ React }}>` -
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
cause React hooks (like `useState`, `useEffect`) were used in the `code` prop but were not explicitly exposed in the `scope` prop or were called outside a functional component.fixEnsure `React.useState`, `React.useEffect`, etc., are provided in the `scope` if used directly, or properly destructure them: `<LiveProvider code={code} scope={{ React, useState: React.useState }}>` -
SyntaxError: Unexpected token '?'
cause Older versions of the internal transpiler (Sucrase) might not fully support all modern JavaScript syntax features like optional chaining or nullish coalescing by default.fixEnsure `react-live` is updated to the latest patch version, as `v4.1.7` specifically fixed optional chaining with Sucrase. If the issue persists with custom transpilers or specific configurations, check their documentation for feature support.
Warnings
- breaking Version 4.1.0 migrated to Prism React Renderer 2. Users who were directly interacting with or customizing internals of Prism React Renderer (e.g., through its context or props) might experience breaking changes due to updated APIs or component structures.
- breaking `react-live` now requires `react` and `react-dom` versions `>=18.0.0` as peer dependencies. Older React versions are no longer officially supported and may lead to runtime errors or unexpected behavior.
- gotcha When using `LiveProvider`, the `scope` prop must contain all variables and components that are referenced within the `code` string but are not globally available. Failing to include them will result in 'undeclared variable' errors.
- gotcha The `render` function implicitly provided in the `code` prop within `LiveProvider` expects a single React element. Attempting to return multiple elements or plain text without wrapping them may lead to rendering issues or errors.
Install
-
npm install react-live -
yarn add react-live -
pnpm add react-live
Imports
- LiveProvider
const { LiveProvider } = require('react-live');import { LiveProvider } from 'react-live'; - LiveEditor
import LiveEditor from 'react-live/LiveEditor';
import { LiveEditor } from 'react-live'; - LivePreview
const LivePreview = require('react-live').LivePreview;import { LivePreview } from 'react-live'; - LiveError
import { LiveError } from 'react-live'; - LiveContext
import type { LiveContext } from 'react-live';
Quickstart
import React from 'react';
import { LiveProvider, LiveEditor, LiveError, LivePreview } from 'react-live';
const code = `
function Counter() {
const [count, setCount] = React.useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
render(<Counter />);
`;
const scope = { React, useState: React.useState };
function MyLivePlayground() {
return (
<LiveProvider code={code} scope={scope}>
<div style={{ display: 'flex', gap: '20px' }}>
<div style={{ flex: 1 }}>
<h3>Editor</h3>
<LiveEditor style={{ minHeight: '200px', backgroundColor: '#333', color: '#fff', padding: '10px', borderRadius: '4px' }} />
</div>
<div style={{ flex: 1 }}>
<h3>Preview</h3>
<LivePreview style={{ border: '1px solid #ccc', padding: '10px', borderRadius: '4px' }} />
<h3>Error</h3>
<LiveError style={{ color: 'red', border: '1px solid red', padding: '10px', borderRadius: '4px' }} />
</div>
</div>
</LiveProvider>
);
}
export default MyLivePlayground;