Understanding @magnitudedev/client-common vs @magnitudedev/sdk: Package Roles in Magnitude
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 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 |
Implements MagnitudeClient with recovery logic |
packages/sdk/src/service-starter.ts |
Optional daemon launcher when ACN isn't running |
SDK Usage Example
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 |
Creates the Effect Query client bridging SDK to atoms |
packages/client-common/src/operations/models.ts |
Example high-level operation using SDK under the hood |
packages/client-common/src/index.ts |
Barrel exports for UI package imports |
React Hook Pattern
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
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 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/sdkdelivers the effect-based RPC client (MagnitudeClient) that speaks to the ACN daemon—portable, recoverable, and UI-agnostic.@magnitudedev/client-commonprovides 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). The operation implementation calls SDK methods, while UI components consume it through useAgentClient hooks.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →