# Understanding @magnitudedev/client-common vs @magnitudedev/sdk: Package Roles in Magnitude

> Discover the distinct roles of @magnitudedev/client-common and @magnitudedev/sdk packages in Magnitude. Understand shared UI state and RPC client functionalities for your projects.

- Repository: [Magnitude/magnitude](https://github.com/magnitudedev/magnitude)
- Tags: package-explanation
- Published: 2026-09-06

---

**The `@magnitudedev/client-common` package provides shared UI state, React hooks, and high-level query abstractions for CLI/Web/Desktop clients, while `@magnitudedev/sdk` delivers the low-level, effect-based RPC client that communicates directly with the ACN daemon.**

The Magnitude monorepo enforces a strict **package layering architecture** that cleanly separates user-facing interfaces from daemon internals. These two packages form the critical bridge between your application code and the underlying Agent Control Node (ACN), with each serving a distinct purpose in the request lifecycle.

## Package Architecture Overview

The Magnitude codebase organizes functionality into discrete layers to prevent UI code from leaking into infrastructure concerns. According to the project's [`AGENTS.md`](https://github.com/magnitudedev/magnitude/blob/main/AGENTS.md) documentation, the relationship follows this dependency flow:

- **UI Clients** (CLI, Web, Desktop) → `@magnitudedev/client-common` → `@magnitudedev/sdk` → **ACN Daemon**

This unidirectional dependency chain ensures that no React component or CLI view ever imports directly from the daemon, storage, or provider implementations.

## @magnitudedev/sdk: The Low-Level RPC Layer

The **SDK package** provides a portable, effect-based RPC client that understands only the wire protocol. It handles connection establishment, automatic recovery, and optional service lifecycle management without any knowledge of React, SQLite, or query caching.

### Core Responsibilities

- **Pure RPC transport** via `MagnitudeClient`
- **Connection admission and reconnection policies**
- **Optional service starter** for daemon auto-launch
- **Protocol contract re-exports** (types, schemas)

### Key Implementation Files

| File | Purpose |
|------|---------|
| [`packages/sdk/src/client.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/sdk/src/client.ts) | Implements `MagnitudeClient` with recovery logic |
| [`packages/sdk/src/service-starter.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/sdk/src/service-starter.ts) | Optional daemon launcher when ACN isn't running |

### SDK Usage Example

```typescript
import { MagnitudeClient } from '@magnitudedev/sdk';

const magnitudeClient = MagnitudeClient.make({
  endpoint: process.env.MAGNITUDE_ENDPOINT,
  starter: undefined, // optional ServiceStarter
});

```

The `MagnitudeClient.make` factory returns an Effect-TS client that manages the full connection lifecycle. It remains agnostic to any UI framework or state management system.

## @magnitudedev/client-common: The Shared Client Layer

The **client-common package** builds higher-level abstractions on top of the SDK. It houses all reusable state, React hooks, and domain-specific operations that multiple UI clients need.

### Core Responsibilities

- **Shared state atoms** for client-side caching
- **First-party Query/Mutation/Subscription abstractions**
- **Display synchronization logic**
- **Domain operations** (models, displays, agents)

### Key Implementation Files

| File | Purpose |
|------|---------|
| [`packages/client-common/src/state/agent-client.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/client-common/src/state/agent-client.ts) | Creates the Effect Query client bridging SDK to atoms |
| [`packages/client-common/src/operations/models.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/client-common/src/operations/models.ts) | Example high-level operation using SDK under the hood |
| [`packages/client-common/src/index.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/client-common/src/index.ts) | Barrel exports for UI package imports |

### React Hook Pattern

```typescript
import { useAgentClient } from '@magnitudedev/client-common';
import { modelList } from '@magnitudedev/client-common/operations/models';

export function ModelList() {
  const client = useAgentClient();
  const models = client.useQuery(modelList);

  return (
    <ul>
      {models.map(m => (
        <li key={m.id}>{m.name}</li>
      ))}
    </ul>
  );
}

```

The `useAgentClient` hook retrieves the configured client from React context, while `modelList` represents a declarative operation definition that the client executes via the underlying SDK.

### Subscription Pattern

```typescript
import { useAgentClient } from '@magnitudedev/client-common';
import { displayView } from '@magnitudedev/client-common/operations/display';

export function LiveDisplay() {
  const client = useAgentClient();
  const display = client.useSubscription(displayView);

  return <DisplayView data={display} />;
}

```

Subscriptions receive automatic updates as the ACN daemon streams events through the SDK's persistent connection.

## Architectural Boundaries

Understanding where each package ends is essential for contributing to Magnitude:

| Concern | Belongs To | Never Contains |
|---------|-----------|--------------|
| **Transport protocol, connection state** | `@magnitudedev/sdk` | React hooks, UI atoms |
| **Query caching, optimistic updates** | `@magnitudedev/client-common` | SQLite, process supervision |
| **Daemon lifecycle, provider implementations** | Private packages (`acn`, `providers`) | Direct imports from UI code |

The [`AGENTS.md`](https://github.com/magnitudedev/magnitude/blob/main/AGENTS.md) documentation explicitly prohibits UI layers from reaching into ACN, providers, or storage directly. All access must flow through `client-common` (for operations) and `sdk` (for raw RPC).

## Summary

- **`@magnitudedev/sdk`** delivers the **effect-based RPC client** (`MagnitudeClient`) that speaks to the ACN daemon—portable, recoverable, and UI-agnostic.
- **`@magnitudedev/client-common`** provides **shared state, React hooks, and operation definitions** that CLI, Web, and Desktop clients import to interact with Magnitude services.
- **UI packages import only from these two packages**, never from daemon internals, enforcing clean architectural boundaries.
- The **Effect-TS foundation** enables type-safe, composable async workflows across both layers.

## Frequently Asked Questions

### Can I use @magnitudedev/sdk without React?

Yes. The SDK is deliberately framework-agnostic. It exports only Effect-TS primitives and protocol types. You can use `MagnitudeClient` in Node.js scripts, Vue applications, or any JavaScript runtime without React dependencies.

### Why doesn't client-common re-export everything from the SDK?

Intentional layering. `client-common` selectively exposes SDK functionality through higher-level operations. This prevents UI code from accidentally using low-level RPC methods that bypass caching, optimistic updates, or state synchronization handled by the agent client.

### How does connection recovery work across both packages?

The SDK's `MagnitudeClient` implements automatic reconnection with configurable policies. `client-common` layers **operation-level resilience** on top—retrying failed queries, managing loading states, and keeping UI atoms consistent during transient disconnections.

### Where should I add a new API operation for the UI?

Define the operation in `packages/client-common/src/operations/` following the existing pattern (e.g., [`models.ts`](https://github.com/magnitudedev/magnitude/blob/main/models.ts)). The operation implementation calls SDK methods, while UI components consume it through `useAgentClient` hooks.