# Presence
Room presence and online status
- Package: @bijectionhq/presence
- Category: Collaboration
- Status: Preview
- License: Apache-2.0
- Bijection source (repository access required): https://github.com/bijectionhq/presence/tree/defcc3a72f67569d29ed35897d0739d32b68db54
- Upstream: https://github.com/convex/presence/tree/a7640e7e8e062a747e5a38d1320bd51e3ad8aea7
- Documentation: https://docs.bijection.com/components/using
- Directory: https://bijection.com/components/presence
## Get the source
Bijection repository access is required. Request access at https://bijection.com/contact.
```sh
git clone https://github.com/bijectionhq/presence.git
cd presence
git checkout defcc3a72f67569d29ed35897d0739d32b68db54
```
## Before using this component
Read the package README at the recorded revision for setup, dependencies, and API examples. Upstream documentation describes the original package and may differ from the Bijection adaptation. This is a source candidate for evaluation. Catalog inclusion does not establish npm availability or runtime qualification. Check compatibility with your SDK and deployment before adoption. External providers run their own compute.
## Upstream package documentation
Recorded 2026-10-23. This describes @convex-dev/presence; check the Bijection adaptation separately.
This component provides real-time user presence tracking for rooms or spaces in your application. It efficiently manages who's online, when users were last active, and handles join/leave events without polling or constant query re-execution. The implementation uses Convex scheduled functions to minimize unnecessary updates and includes React hooks for seamless client integration.
### Use cases
- **Building collaborative editors** where you need to show which users are currently viewing or editing a document in real-time
- **Creating chat applications** that display online status indicators and active participant lists for channels or direct messages
- **Implementing multiplayer games** where you track which players are currently in a game room or lobby
- **Adding social features to content platforms** like showing who's currently viewing a live stream, article, or product page
- **Building virtual event platforms** that need to display attendee counts and participant lists for different rooms or sessions
### How it works
The component uses a `Presence` class that wraps Convex scheduled functions to efficiently track user activity. You expose three main functions: `heartbeat` for clients to signal they're active, `list` to query current presence data, and `disconnect` for graceful cleanup when users leave.
Clients use the `usePresence` React hook which automatically sends heartbeat messages at regular intervals and handles cleanup when components unmount or tabs close. The hook takes your presence API, a room identifier, and user information, returning live presence state that updates when users join or leave.
The component includes a basic `FacePile` component for displaying user avatars, but you can use the `usePresence` hook directly to build custom UI. Additional functions like `listUser` let you check if specific users are online across any room. React Native support is available through a separate import path.
### Upstream README
# Presence Convex Component
A Convex component for managing presence functionality, i.e., a live-updating
list of users in a "room" including their status for when they were last online.
It can be tricky to implement presence efficiently, without any polling and
without re-running queries every time a user sends a heartbeat message. This
component implements presence via a single deployment-wide worker (a
[batch-worker](https://github.com/get-convex/batch-worker) loop) that sleeps
until the next session timeout is due, such that clients only receive updates
when a user joins or leaves the room and heartbeats don't schedule any work.
The most common use case for this component is via the usePresence hook, which
takes care of sending heartbeart messages to the server and gracefully
disconnecting a user when the tab is closed.
## Installation
```bash
npm install @convex-dev/presence
```
## Examples
See the `example` directory for a simple example of how to use this component.
The `example-with-auth` directory shows how to use the component with
authentication.
There's a hosted version of `example-with-auth` at
https://presence.previews.convex.dev.
## Usage
First, add the component to your Convex app:
`convex/convex.config.ts`
```ts
import { defineApp } from "convex/server";
import presence from "@convex-dev/presence/convex.config.js";
const app = defineApp();
app.use(presence);
export default app;
```
`convex/presence.ts`
```ts
import { mutation, query } from "./_generated/server";
import { components } from "./_generated/api";
import { v } from "convex/values";
import { Presence } from "@convex-dev/presence";
export const presence = new Presence(components.presence);
export const heartbeat = mutation({
args: {
roomId: v.string(),
userId: v.string(),
sessionId: v.string(),
interval: v.number(),
},
handler: async (ctx, { roomId, userId, sessionId, interval }) => {
// TODO: Add your auth checks here.
return await presence.heartbeat(ctx, roomId, userId, sessionId, interval);
},
});
export const list = query({
args: { roomToken: v.string() },
handler: async (ctx, { roomToken }) => {
// Avoid adding per-user reads so all subscriptions can share same cache.
return await presence.list(ctx, roomToken);
},
});
export const disconnect = mutation({
args: { sessionToken: v.string() },
handler: async (ctx, { sessionToken }) => {
// Can't check auth here because it's called over http from sendBeacon.
return await presence.disconnect(ctx, sessionToken);
},
});
```
A `Presence` React component can be instantiated from your client code like
this:
`src/App.tsx`
```tsx
import { api } from "../convex/_generated/api";
import usePresence from "@convex-dev/presence/react";
import FacePile from "@convex-dev/presence/facepile";
export default function App(): React.ReactElement {
const [name] = useState(() => "User " + Math.floor(Math.random() * 10000));
const presenceState = usePresence(api.presence, "my-chat-room", name);
return (
);
}
```
This uses the basic `FacePile` component included with this package but you can
easily copy this code and use the `usePresence` hook directly to implement your
own styling.
### React Native support
If you're using React Native, install these optional dependencies:
```sh
npx expo install react-native expo-crypto
```
and then import the `usePresence` hook from `@convex-dev/presence/react-native`:
```ts
import { usePresence } from "@convex-dev/presence/react-native";
```
_Note: The component currently doesn't have a React Native
equivalent, but you can easily create your own._
## Additional functionality
The component interface for the `Presence` class is defined in
`src/client/index.ts`. It includes additional functions for maintaining presence
state and for querying presence for a given user or room.
e.g., you can use the `listUser` function to check if a user is online in any
room.
Reach out or join the [Convex Discord Community](https://convex.dev/community)
if you have any questions or feedback!