> ## Documentation Index
> Fetch the complete documentation index at: https://docs.twenty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CodeEditor

> Edit and display code in a Monaco editor styled with the Twenty theme.

export const StoryEmbed = ({storyId, title, height = 240}) => <>
    <Tabs>
      <Tab title="Light">
        <iframe title={`${title} (light)`} src={`https://storybook.twenty.com/iframe.html?id=${storyId}&viewMode=story&globals=colorScheme:light`} width="100%" height={height} loading="lazy" style={{
  border: 0
}} />
      </Tab>
      <Tab title="Dark">
        <iframe title={`${title} (dark)`} src={`https://storybook.twenty.com/iframe.html?id=${storyId}&viewMode=story&globals=colorScheme:dark`} width="100%" height={height} loading="lazy" style={{
  border: 0
}} />
      </Tab>
    </Tabs>
    <a href={`https://storybook.twenty.com/?path=/story/${storyId}`}>
      Open in Storybook
    </a>
  </>;

`CodeEditor` renders a [Monaco](https://microsoft.github.io/monaco-editor/) editor that follows the Twenty theme in light and dark mode. `CodeEditorHeader` adds a bar above it for a title, tabs, or actions. Both come from `twenty-ui/components/code-editor`, a separate entry point, so the rest of Twenty UI works without Monaco.

<StoryEmbed storyId="ui-components-codeeditor--documentation" title="Code editor example" height={280} />

## Setup

Install the editor's optional peer dependencies:

```bash theme={null}
yarn add @monaco-editor/react monaco-editor
```

The editor loads your installed `monaco-editor` package rather than a copy from a CDN. Monaco runs language features such as validation and autocompletion in web workers, and creating those workers depends on your bundler. Before an editor mounts, define `MonacoEnvironment.getWorker` as described in [Monaco's ESM integration guide](https://github.com/microsoft/monaco-editor/blob/main/docs/integrate-esm.md). Without it, the editor still renders, but language features are unavailable.

The code editor does not run inside [front components](/developers/extend/apps/layout/front-components) yet.

## Usage

```tsx theme={null}
import { useState } from 'react';
import { CodeEditor } from 'twenty-ui/components/code-editor';

export const PayloadEditor = () => {
  const [payload, setPayload] = useState('{\n  "name": "Acme"\n}');

  return (
    <CodeEditor
      language="json"
      value={payload}
      onChange={setPayload}
      height={200}
    />
  );
};
```

`onChange` receives the full content on every change. A loader shows until Monaco has loaded. Set `isLoading` to keep showing it while your own data loads.

## Add a header

```tsx theme={null}
import { CodeEditor, CodeEditorHeader } from 'twenty-ui/components/code-editor';
import { Button } from 'twenty-ui/primitives/input';

type ScriptEditorProps = {
  script: string;
  onRun: () => void;
};

export const ScriptEditor = ({ script, onRun }: ScriptEditorProps) => (
  <div>
    <CodeEditorHeader
      title="index.ts"
      rightNodes={[
        <Button key="run" size="sm" onClick={onRun}>
          Run
        </Button>,
      ]}
    />
    <CodeEditor language="typescript" value={script} variant="with-header" />
  </div>
);
```

`variant="with-header"` removes the editor's top border so it joins the header. Use `borderless` when the editor sits inside a surface that already has a border.

## Size and appearance

The editor is 450px tall by default. Set `height` to a number of pixels or a CSS length. `autoHeight` grows the editor with its content, and `resizable` adds a handle below it to drag the height. When both are set, `resizable` applies.

`contentPadding="comfortable"` widens the gap between line numbers and code. `transparentBackground` lets the surrounding surface show through.

## Validation

Monaco reports its own diagnostics, such as JSON syntax errors, through `onValidate`. To add your own, return marker data from `setMarkers`. It runs when the editor mounts and after every change, and replaces the markers it set before.

## Keyboard

While the editor has focus, it stops keyboard events from propagating. React key handlers on parent components and document-level shortcuts do not receive keystrokes typed in the editor.

## Props

### CodeEditor

<ParamField body="autoHeight" type="boolean" default="false">
  Grows the editor to fit its content instead of using `height`. Ignored when `resizable` is set.
</ParamField>

<ParamField body="contentPadding" type="&#x22;default&#x22; | &#x22;comfortable&#x22;" default="default">
  `default` pads the top and bottom of the content. `comfortable` also widens the gap between line numbers and code.
</ParamField>

<ParamField body="height" type="string | number" default="450">
  Editor height in pixels or as a CSS length. With `resizable`, a numeric height sets the initial height.
</ParamField>

<ParamField body="isLoading" type="boolean" default="false">
  Shows a loader at the editor height instead of the editor. A loader also shows while Monaco loads.
</ParamField>

<ParamField body="language" type="string">
  Monaco language identifier for highlighting and language services, such as `json` or `typescript`.
</ParamField>

<ParamField body="onChange" type="((value: string) => void)">
  Called with the full content whenever it changes.
</ParamField>

<ParamField body="onMount" type="OnMount">
  Called when the editor is ready, with the editor instance and the Monaco namespace. The Twenty theme is already applied.
</ParamField>

<ParamField body="onValidate" type="OnValidate">
  Called with the markers Monaco reports after validating the content, such as JSON syntax errors.
</ParamField>

<ParamField body="options" type="IStandaloneEditorConstructionOptions">
  Monaco editor options merged over the Twenty defaults. `padding` is ignored; use `contentPadding` instead.
</ParamField>

<ParamField body="resizable" type="boolean" default="false">
  Adds a handle below the editor to drag its height.
</ParamField>

<ParamField body="setMarkers" type="((value: string) => IMarkerData[])">
  Returns custom validation markers for the content. Runs when the editor mounts and after every change, replacing the previous custom markers.
</ParamField>

<ParamField body="transparentBackground" type="boolean">
  Removes the editor background so the surrounding surface shows through.
</ParamField>

<ParamField body="value" type="string">
  Content of the editor. Pair it with `onChange` to control the editor.
</ParamField>

<ParamField body="variant" type="&#x22;default&#x22; | &#x22;with-header&#x22; | &#x22;borderless&#x22;" default="default">
  Border treatment: `default` draws a rounded border, `with-header` attaches the editor below a `CodeEditorHeader`, and `borderless` removes the border.
</ParamField>

### CodeEditorHeader

<ParamField body="leftNodes" type="ReactNode[]">
  Elements shown at the start of the header, such as tabs.
</ParamField>

<ParamField body="rightNodes" type="ReactNode[]">
  Elements shown at the end of the header, such as actions.
</ParamField>

<ParamField body="title" type="string">
  Text shown at the start of the header, after `leftNodes`.
</ParamField>
