Ember Link
The Open-Source SDK for Real-Time Collaboration
Ember Link makes it effortless to add real-time collaboration to your apps. Whether you're building a document editor, whiteboard, or any interactive experience, Ember Link provides the tools you needm with the flexibility to self-host for full control over privacy and customization.
Built for Performance & Reliability
Made with Rust and TypeScript, Ember Link ensures strong type safety, high performance, and an easy-to-use API without compromising power.
Key Features:
- ✅ User Presence Tracking - Know who's online and active in real time.
- ✅ Custom Messaging - Send and receive real-time messages between clients.
- ✅ Shared Storage with CRDTs - Conflict-free data synchronization for seamless collaboration.
- ✅ Collaborative Editing - Synchronize edits across users with shared storage.
Quickstart
Ember Link is designed to be intuitive and developer-friendly. Here's how easy it is to integrate:
import { createClient } from '@ember-link/core';
const client = createClient({
baseUrl: 'http://localhost:9000'
});
const { channel } = client.joinChannel('test');
/**
* Subscribe to every others presence updates.
* The callback will be called if
* someone else enters or leaves the channel
* or when someones presence is updated
*/
channel.events.others.subscribe('join', (user) => {
console.log('User join: ', user);
});
channel.events.others.subscribe('update', (user) => {
console.log('User update: ', user);
});
channel.events.others.subscribe('leave', (user) => {
console.log('User leave: ', user);
});
import { createClient } from '@ember-link/core';
const client = createClient({
baseUrl: 'http://localhost:9000'
});
const { channel } = client.joinChannel('test');
/**
* Subscribe to every others presence updates.
* The callback will be called if
* someone else enters or leaves the channel
* or when someones presence is updated
*/
channel.events.others.subscribe('join', (user) => {
console.log('User join: ', user);
});
channel.events.others.subscribe('update', (user) => {
console.log('User update: ', user);
});
channel.events.others.subscribe('leave', (user) => {
console.log('User leave: ', user);
});
import { ChannelProvider, EmberLinkProvider } from '@ember-link/react';
function App() {
return (
<EmberLinkProvider baseUrl="http://localhost:9000">
<ChannelProvider channelName="test" options={{}}>
<Page />
</ChannelProvider>
</EmberLinkProvider>
);
}
function Page() {
const others = useOthers();
const [myPresence, setMyPresence] = useMyPresence();
useEffect(() => {
setMyPresence({ status: 'online' });
}, [setMyPresence]);
return (
<div>
{myPresence}
{others.map((other) => {
return <div>{other.clientId}</div>;
})}
</div>
);
}
<!-- +layout.tsx -->
<script lang="ts">
import '../app.css';
import { EmberLinkProvider, ChannelProvider } from '@ember-link/svelte';
let { children } = $props();
</script>
<EmberLinkProvider baseUrl="http://localhost:9000">
<ChannelProvider channelName="test">
{@render children()}
</ChannelProvider>
</EmberLinkProvider>
<!-- +page.tsx -->
<script lang="ts">
import { getChannelContext } from '@ember-link/svelte';
const channel = getChannelContext();
</script>
<div>
{channel.myPresence}
{#each channel.others as other (other.clientId)}
{other.clientId}
{/each}
</div>
Ember Link makes real-time collaboration powerful yet simple. Get started today and bring seamless teamwork to your app! 🚀