Files
supabase/apps/ui-library/content/docs/react/realtime-monaco.mdx
Tiago AntunesandIvan Vasilov 9bf981f371 feat(ui-library): add Realtime Monaco ui component (#41766)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES
## What kind of change does this PR introduce?

Adds a new Realtime Monaco component to the UI Library, enabling
collaborative code editing with Supabase Realtime synchronization using
Monaco Editor and Yjs.

## Additional context

This is WIP and used for discuss further changes to the y-supabase
provider.

## Demo

https://github.com/user-attachments/assets/84a761e5-73bb-478e-979a-682121ffee89



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added a new Realtime Monaco collaborative code editor component with
real-time synchronization support across multiple frameworks (Next.js,
React, React Router, Tanstack).

* **Documentation**
* Added comprehensive documentation and usage guides for the Realtime
Monaco component across all supported frameworks.

* **Dependencies**
* Added Monaco editor, Yjs, y-monaco, and Supabase collaboration
packages.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-03-17 13:55:03 +01:00

125 lines
5.7 KiB
Plaintext

---
title: Realtime Monaco
description: Real-time Monaco editor for collaborative applications
---
<DualRealtimeMonaco />
## Installation
<BlockItem
name="realtime-monaco-react"
description="Real-time Monaco editor for collaborative applications."
/>
## Folder structure
<RegistryBlock itemName="realtime-monaco-react" />
## Introduction
The Realtime Monaco component provides a collaborative code editor powered by [Monaco](https://microsoft.github.io/monaco-editor/) and [Yjs](https://yjs.dev/). It uses [`@supabase-labs/y-supabase`](https://github.com/supabase-community/y-supabase) under the hood to sync document state across clients through Supabase Realtime.
**Features**
- Real-time document synchronization via Supabase Realtime broadcast
- Cursor and selection sharing between collaborators (awareness)
- Optional persistence to Postgres so documents survive page reloads
- Supports all Monaco languages and themes
- Room-based isolation for scoped collaboration
## How it works under the hood
The component creates a [Yjs](https://yjs.dev/) document and connects it to a Supabase Realtime channel using `SupabaseProvider` from `@supabase-labs/y-supabase`. A `MonacoBinding` from `y-monaco` bridges the Yjs document with the Monaco editor model, keeping them in sync.
When **awareness** is enabled, each user's cursor position and selection are broadcast to other clients in the same channel. Remote cursors are rendered with unique colors via dynamically injected CSS.
When **persistence** is enabled, the full Yjs document state is saved to a Postgres table so it can be restored when clients reconnect.
## Usage
### Basic usage
```tsx
import { RealtimeMonaco } from '@/components/realtime-monaco'
export default function MonacoPage() {
return <RealtimeMonaco channel="realtime-monaco-demo" language="typescript" />
}
```
### With persistence
Enable persistence to save the editor content to your Supabase database. This requires a table to store the Yjs document state.
First, create the required table in your Supabase project:
```sql
create table yjs_documents (
room text primary key,
state text not null
);
```
Then pass `persistence` to the component:
```tsx
import { RealtimeMonaco } from '@/components/realtime-monaco'
export default function MonacoPage() {
return <RealtimeMonaco channel="realtime-monaco-demo" language="typescript" persistence />
}
```
You can also pass a `SupabasePersistenceOptions` object:
```tsx
<RealtimeMonaco
channel="realtime-monaco-demo"
language="typescript"
persistence={{
table: 'yjs_documents',
roomColumn: 'room',
stateColumn: 'state',
storeTimeout: 2000,
}}
/>
```
### Without awareness
By default, cursor and selection positions are shared between collaborators. To disable this:
```tsx
<RealtimeMonaco channel="realtime-monaco-demo" awareness={false} />
```
## Props
| Prop | Type | Description |
| -------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `channel` | `string` | Unique channel name used to sync editor content between collaborators in the same session. |
| `language?` | `string` | Monaco [language identifier](https://code.visualstudio.com/docs/languages/identifiers) (e.g. `typescript`, `python`). Defaults to `javascript`. |
| `height?` | `string \| number` | Height of the editor container. Accepts a pixel number or CSS string (e.g. `"100%"`). Defaults to `550`. |
| `className?` | `string` | CSS class applied to the editor wrapper element. |
| `awareness?` | `boolean \| Awareness` | Enables cursor and selection sharing between users. Pass `false` to disable or a custom `Awareness` instance. Defaults to `true`. |
| `persistence?` | `boolean \| SupabasePersistenceOptions` | Persists editor content to Supabase so it survives page reloads. Pass `true` for defaults or an options object for fine-grained control. |
| `theme?` | `'light' \| 'dark'` | Color theme for the editor. Maps to Monaco's `light` and `vs-dark` themes. |
### SupabasePersistenceOptions
| Option | Type | Default | Description |
| -------------- | -------- | ----------------- | --------------------------------------------------- |
| `table` | `string` | `'yjs_documents'` | Name of the Postgres table used to store documents. |
| `schema` | `string` | `'public'` | Schema where the table is located. |
| `roomColumn` | `string` | `'room'` | Column used as the document identifier. |
| `stateColumn` | `string` | `'state'` | Column used to store the binary Yjs state. |
| `storeTimeout` | `number` | `1000` | Debounce delay (ms) before persisting changes. |
## Further reading
- [Realtime Broadcast](https://supabase.com/docs/guides/realtime/broadcast)
- [Realtime authorization](https://supabase.com/docs/guides/realtime/authorization)
- [`@supabase-labs/y-supabase`](https://github.com/supabase-community/y-supabase)
- [Yjs documentation](https://docs.yjs.dev/)