Custom app
Build a custom collaborative application when no ready-made editor or integration matches your interface, for example an issue tracker, CRM, dashboard, or internal tool. Synchronize your application state, show live collaborators, and layer on activity feeds, comments, notifications, and AI editing as your product needs them.

Custom realtime features in the Linear-like Issue Tracker example
Features
- Realtime collaboration: Application state is permanent & updates in realtime for connected users.
- Presence: Show avatar stacks, live selections, multiplayer cursors, and agent activity.
- Activity feed: Show a persistent, realtime timeline of everything happening in your app.
- Revalidating API data: Tell other clients to refetch data stored in your own database.
- Server-side editing: Modify application state from a trusted back end.
- Agentic editing: Generate and apply validated changes with AI.
- Version history: Save, preview, and restore application state from snapshots.
- Multiplayer undo/redo: Each user can independently undo and redo their own changes.
- File uploads: Attach uploaded files to your application records.
- Comments: Attach commenting threads to any record in your app.
- Notifications: Notify users about mentions, assignments, and custom events.
- Permissions: Control which users can read and edit the app.
Get started
Choose a starting point for your app.
Implementation
This is an overview of how each feature can be implemented, using an issue tracker as the example app. Sync can be used to store any type of permanent realtime data, such as issues. Presence can hold temporary selections and interaction state, and Feeds can store durable activity streams.
Realtime collaboration
Using Sync, you can add realtime collaboration
to your application state using
conflict-free data types. In this snippet, a
realtime “priority” property can be read and edited using
useStorage and
useMutation.
Learn more under Storage.
Presence
Using presence, you can show avatar stacks, live selections, and agent activity
in your app. To build a custom avatar stack, read connected collaborators with
useOthers and the current
user with useSelf, then render
the user data returned by
resolveUsers.
Learn more under Presence.
Activity feed
Using Feeds, you can add a persistent, realtime
activity feed to your app, for example a timeline of status changes,
assignments, and activity on an issue. Render the timeline with
useFeedMessages and
append events with
useCreateFeedMessage.
Your server and background workflows can append to the same feed with
Liveblocks.createFeedMessage,
and the same primitives also power chat interfaces and AI agent progress. Learn
more under Feeds.
Revalidating API data
You can keep some app data in your own database rather than in
Sync, and still make it feel realtime. When a
user saves a change through your API, use
useBroadcastEvent to
send a transient broadcast event to the other
connected clients, and
useEventListener to
revalidate the cached data when it arrives, for example with SWR.
Broadcast events are not persisted—use them for signals, not for state. Read revalidating API data with SWR for the full pattern, and learn more under events.
Server-side editing
Edit your application state from your server with
Liveblocks.mutateStorage,
for example to add a link to an issue. The mutation uses the same Sync data
types as the client, and connected users receive the result in realtime.
Read Server-side editing for validation, versioning, bulk mutations, and other document formats.
Agentic editing
To allow AI agents to modify your app, generate your changes with AI then use
mutateStorage to apply
them. To show that AI is working in your app use
setPresence
to show it working—your agent will appear in Presence alongside
humans. Finally, remove the agent’s presence to indicate that the agent is no
longer working.
Additionally, you can use Feeds to store AI workflow state, and to pass agent status updates to the UI. Learn more under Agentic editing.
Version history
Create version snapshots, manually or automatically, list old versions, and
restore to a specific version—useful before bulk imports or large agent edits.
Use
useHistoryVersions
to list versions,
useHistoryVersionStorageData
to render a read-only preview, and
useRestoreToStorageVersion
to restore the complete application Storage state as one synchronized change.
Read Version history to learn more.
Multiplayer undo/redo
Each user can independently undo and redo their own changes with
useUndo and
useRedo. Additionally,
useCanUndo and
useCanRedo can be used to
disable the undo and redo buttons when the user is at the beginning or end of
the undo/redo stack.
History can also be paused, resumed, and disabled. Read Multiplayer undo/redo to learn more.
File uploads
You can upload files and other binary assets with
useUploadFile, for
example to attach a screenshot to an issue. It uploads the file to the current
room as a LiveFile, which
you can then attach to your data tree.
Learn more under File uploads.
Comments
Add commenting to your app, for example as a discussion section below each
issue. useThreads allows
you to fetch the threads for a specific record, while the
Thread and
Composer components render
discussions and create new ones.
Learn more under Comments.
Notifications
Using Notifications, you can create an inbox
tray that notifies users about mentions and replies in comments. You can also
trigger custom notifications for your own application events, such as an issue
being assigned to a user. Render the current user’s inbox with
useInboxNotifications
and the ready-made
InboxNotification
component.
You can trigger custom notifications with
Liveblocks.triggerInboxNotification.
Learn more under Notifications.
Permissions
Each part of your app is contained inside a room in your Liveblocks app, and
permission groups can set access to it. For example, your issue board may have
an editor group and a viewer group. This can be set when modifying or creating a
room, for example with
Liveblocks.createRoom.
More complex controls can be set too, learn more under Permissions.
Examples
Explore complete implementations in our example gallery.