Quickstart: React SDK

Build your first AI-powered React component in 5 minutes.

Step 1 — Install the React SDK

pnpm add @arlopass/react

Step 2 — Wrap your app in ArlopassProvider

The provider connects to the browser extension and manages the AI client lifecycle.

import { ArlopassProvider } from "@arlopass/react";

function App() {
  return (
    <ArlopassProvider appId="my-app">
      <YourApp />
    </ArlopassProvider>
  );
}

Step 3 — Add ChatReadyGate

The gate handles loading, missing-provider, and error states so your chat component only renders when everything is ready.

import { ChatReadyGate } from "@arlopass/react";

function YourApp() {
  return (
    <ChatReadyGate
      connecting={<p>Connecting to extension...</p>}
      noProvider={<p>Please select a provider in the extension.</p>}
      error={(err) => <p>Error: {err.message}</p>}
    >
      <Chat />
    </ChatReadyGate>
  );
}

Step 4 — Use the useConversation hook

The hook gives you the message list, a streaming send function, and status flags. No manual state management needed.

import { useConversation } from "@arlopass/react";

function Chat() {
  const { messages, stream, isStreaming } = useConversation();

async function handleSend(text: string) {
    await stream({
      messages: [...messages, { role: "user", content: text }],
    });
  }

return /* your UI */;
}

Step 5 — Build the UI

Wire up an input and a message list. The hook handles the rest.

import { useState } from "react";
import { useConversation } from "@arlopass/react";

function Chat() {
  const { messages, stream, isStreaming } = useConversation();
  const [input, setInput] = useState("");

async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!input.trim() || isStreaming) return;
    const text = input;
    setInput("");
    await stream({
      messages: [...messages, { role: "user", content: text }],
    });
  }

return (
    <div>
      <div>
        {messages.map((msg, i) => (
          <div key={i}>
            <strong>{msg.role}:</strong> {msg.content}
          </div>
        ))}
      </div>
      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Type a message..."
          disabled={isStreaming}
        />
        <button type="submit" disabled={isStreaming}>
          Send
        </button>
      </form>
    </div>
  );
}

Complete example

Here’s a full working chat component you can drop into any React app:

import { useState } from "react";
import {
  ArlopassProvider,
  ChatReadyGate,
  useConversation,
} from "@arlopass/react";

function Chat() {
  const { messages, stream, isStreaming } = useConversation();
  const [input, setInput] = useState("");

return (
    <div>
      <div>
        {messages.map((msg, i) => (
          <div key={i}>
            <strong>{msg.role}:</strong> {msg.content}
          </div>
        ))}
      </div>
      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Type a message..."
          disabled={isStreaming}
        />
        <button type="submit" disabled={isStreaming}>
          Send
        </button>
      </form>
    </div>
  );
}

export default function App() {
  return (
    <ArlopassProvider appId="my-app">
      <ChatReadyGate
        connecting={<p>Connecting...</p>}
        noProvider={<p>Select a provider in the Arlopass extension.</p>}
        error={(err) => <p>Error: {err.message}</p>}
      >
        <Chat />
      </ChatReadyGate>
    </ArlopassProvider>
  );
}

React SDK vs Web SDK

The React SDK wraps the same Web SDK calls in hooks and components. Here’s the same “send a message” feature in both:

React SDK

import { useConversation } from "@arlopass/react";

function Chat() {
  const { messages, stream, isStreaming } = useConversation();

async function send(text: string) {
    await stream({
      messages: [...messages, { role: "user", content: text }],
    });
  }
}

Web SDK

import { ArlopassClient } from "@arlopass/web-sdk";

const client = new ArlopassClient({ transport: window.arlopass });
await client.connect({ appId: "my-app" });

const providers = await client.listProviders();
await client.selectProvider(providers[0].id);

const response = await client.chat.send({
  messages: [{ role: "user", content: "Hello!" }],
});