Cariosan

Quick start

Run Cariosan locally and send your first message in under five minutes.

5 min readUpdated Apr 22, 2026

Stand up Cariosan locally and send your first message. You need Docker Engine 24+ with the Compose plugin.

Or skip Docker entirely

Sign up at dashboard.cariosan.com for a fully-managed workspace — your api_key + api_secret are waiting in the dashboard, no Docker required. See Cariosan Cloud onboarding. The rest of this quick-start is the self-host path.

1

Boot the stack

Download configuration files and start the service — Cariosan server, Postgres, Redis, MinIO:

bash
curl -O https://cariosan.com/docker-compose.yml
curl -O https://cariosan.com/.env.example
mv .env.example .env

The .env template works out of the box for local play. Before you put anything on the public internet, see environment variables for the secrets you must override.

bash
docker compose up -d
curl http://localhost:8080/healthz
# -> {"status":"ok"}
2

Create a workspace

Every call to Cariosan happens in a workspace. Bootstrap one with the built-in CLI:

bash
docker compose exec cariosan-server /cariosan workspace create \
  --name "My Company" --plan free

Save the credentials

The command prints an api_key and api_secret. Copy them now — the secret is only shown once.

3

Create users and a channel

Use the Go server SDK from your backend. This example runs as a standalone main.go:

go
package main
 
import (
	"context"
	"fmt"
	"time"
 
	cariosan "github.com/cariosan/cariosan-go"
)
 
func main() {
	client := cariosan.New(
		"pk_live_abc", "sk_live_xyz", "http://localhost:8080",
	)
	ctx := context.Background()
 
	for _, u := range []string{"alice", "bob"} {
		if _, err := client.UpsertUser(ctx, cariosan.UpsertUserRequest{
			ExternalID: "user_" + u,
			Name:       u,
		}); err != nil {
			panic(err)
		}
	}
 
	ch, err := client.CreateChannel(ctx, cariosan.CreateChannelRequest{
		Type:              cariosan.ChannelGroup,
		ExternalID:        "team_1",
		Name:              "Team",
		MemberExternalIDs: []string{"user_alice", "user_bob"},
	})
	if err != nil {
		panic(err)
	}
 
	tok, _ := client.IssueUserToken(ctx, "user_alice", 24*time.Hour)
	fmt.Println("channel:", ch.ExternalID)
	fmt.Println("alice token:", tok.Token)
}
4

Send a message from the browser

The TypeScript client SDK does the rest:

typescript
import { Cariosan } from "@cariosan/client";
 
const client = new Cariosan({
  apiUrl: "http://localhost:8080",
  token: "<paste alice's JWT from step 3>",
});
await client.connect();
 
const team = client.channel("team_1");
team.on("message", (msg) => console.log(`${msg.user.name}: ${msg.content}`));
 
await team.sendMessage({ text: "Halo from alice!" });

Tip

Open a second browser tab with Bob's JWT (issue a second token from the Go backend) and the message handler fires within ~50ms.

What's next

  • Drop-in React UI@cariosan/react ships ChatProvider, ChannelList, MessageList, MessageInput, TypingIndicator, PresenceBadge, and matching headless hooks. Wrap your app in <ChatProvider client={client}> and the components handle subscribe/unsubscribe automatically.
  • Production deployself-hosting guide covers TLS, backup, rotation.
  • Webhooks — wire push notifications and audit logs via webhook subscribers.

Was this page helpful?

On this page