# Web SDK vs React SDK

### Two SDKs, one protocol

Arlopass ships two SDKs. The Web SDK (`@arlopass/web-sdk`) is the core — a framework-agnostic TypeScript client that handles connections, state machines, envelope construction, and streaming. The React SDK (`@arlopass/react`) wraps the Web SDK with hooks, providers, error boundaries, and a reactive state layer. They speak the same protocol and use the same transport.

### Side-by-side comparison

| Dimension            | Web SDK                                                      | React SDK                                              |
|----------------------|-------------------------------------------------------------|-------------------------------------------------------|
| **Setup**            | Create client, pass transport, manage lifecycle manually    | Wrap in `<ArlopassProvider>`, hooks handle lifecycle  |
| **State management** | Manual — poll getters or build your own reactive layer     | Automatic — ClientStore + useSyncExternalStore        |
| **Error handling**   | try/catch around every operation                            | ArlopassErrorBoundary + error state in hooks          |
| **Streaming**        | for-await-of loop, manual DOM updates                       | Hook returns streaming content, RAF-batched re-renders|
| **Testing**          | Mock the ArlopassTransport interface directly                | createMockTransport + render with ArlopassProvider    |
| **Bundle size**      | Smaller — no React dependency                                | Includes web-sdk + React integration layer             |
| **Framework**        | Any — vanilla JS, Vue, Svelte, Angular                      | React 18+ only                                        |

### When to use the Web SDK

Use the Web SDK when you're not using React — vanilla JavaScript, Vue, Svelte, Angular, or any other framework. It's also the right choice when you need full control over the client lifecycle, want to build your own reactive abstraction on top, or need the smallest possible bundle.

```ts
import { ArlopassClient, ConversationManager } 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({ providerId: "ollama", modelId: "llama3" });

const convo = new ConversationManager({ client });
for await (const event of convo.stream("Hello!")) {
    if (event.type === "token") process.stdout.write(event.token);
}

await client.disconnect();
```

### When to use the React SDK

Use the React SDK when you're building a React application and want managed state, automatic re-renders, streaming optimization, error boundaries, and a hooks-based API. It handles the hard parts — state synchronization, concurrent rendering safety, and streaming batching — so you can focus on your UI.

```tsx
import {
  ArlopassProvider,
  useConnection,
  useProviders,
  useChat,
} from "@arlopass/react";

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

function Chat() {
  const { state } = useConnection();
  const { providers, select } = useProviders();
  const { messages, stream } = useChat({ systemPrompt: "Be helpful." });

// State management, error handling, streaming optimization —
  // all handled by the hooks. You write the UI.
}
```

### Hook-to-pattern mapping

Every React SDK hook replaces a specific Web SDK pattern. If you're familiar with the Web SDK, this mapping shows what each hook encapsulates.

```ts
// Each React hook replaces a manual Web SDK pattern:

// useConnection()     → client.connect() / client.disconnect() / client.state
// useProviders()      → client.listProviders() / client.selectProvider()
// useChat()           → client.chat.send() / client.chat.stream()
// useConversation()   → new ConversationManager({ client })
// useClient()         → escape hatch — returns the raw ArlopassClient
// ArlopassChatReadyGate   → if (state === "connected" && selectedProvider)
```

```tsx
import { useClient } from "@arlopass/react";

function AdvancedFeature() {
  // useClient() gives you the raw ArlopassClient when you need full control.
  // The React SDK wraps @arlopass/web-sdk — so all web-sdk types
  // are re-exported from @arlopass/react.
  const client = useClient();

// You can use client directly for operations not covered by hooks,
  // but you lose automatic state sync and streaming optimization.
  // Use sparingly.
}
```

### Using both

Because the React SDK wraps the Web SDK, you're already using both. Types like `ProviderDescriptor`, `ClientState`, and `ChatStreamEvent` are re-exported from `@arlopass/react`. You don't need to install `@arlopass/web-sdk` separately unless you're importing something the React SDK doesn't re-export (which is rare).

### Migration path

If you started with the Web SDK and want to move to React, the migration is additive. Wrap your app in `ArlopassProvider`, replace imperative client calls with hooks, and remove your manual state management code. Your existing type imports keep working because the React SDK re-exports them.

```ts
// If you started with the Web SDK and want to add React SDK:

// Before — manual state management
const client = new ArlopassClient({ transport: window.arlopass });
// ... manage state, re-renders, cleanup yourself

// After — wrap in ArlopassProvider, use hooks
import { ArlopassProvider, useConnection } from "@arlopass/react";

// The React SDK re-exports web-sdk types, so your existing
// type imports still work:
import type { ProviderDescriptor, ClientState } from "@arlopass/react";

// Migration is additive — you don't rewrite anything,
// you wrap and replace imperative code with hooks.
```
