> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript SDK Overview

> A headless, framework-agnostic SDK for authentication, wallets, and signing. You build the UI — Dynamic handles everything else.

The JavaScript SDK (`@dynamic-labs-sdk/client`) works in **any environment that runs JavaScript** — React, React Native, Vue, Svelte, vanilla JS, or another framework. It gives you full control over authentication, wallet connections, and transaction signing without any built-in UI. You create a Dynamic client, add extensions for the chains you support, and call functions directly — rendering every screen, button, and input yourself.

<Warning>
  This SDK is headless. There is no built-in modal, wallet picker, or login
  form. You are responsible for building all user-facing UI.
</Warning>

## Choose your quickstart

Pick the path that matches how you build:

<CardGroup cols={1}>
  <Card title="React" icon="react" href="/docs/javascript/reference/react-quickstart">
    Vite React apps with `@dynamic-labs-sdk/react-hooks`.
  </Card>

  <Card title="React Native" icon="mobile-screen" href="/docs/javascript/reference/react-native-quickstart">
    Expo or bare React Native with the same client and hooks.
  </Card>

  <Card title="Vanilla JavaScript" icon="js" href="/docs/javascript/reference/quickstart">
    Framework-free or any other JS environment.
  </Card>
</CardGroup>

## How it works

<Steps>
  <Step title="Create a client">
    Call `createDynamicClient()` with your environment ID from the
    [Dynamic dashboard](https://app.dynamic.xyz). This is the single entry point
    for the SDK.
  </Step>

  <Step title="Add extensions">
    Register chain extensions (e.g. `addEvmExtension()`, `addSolanaExtension()`)
    to enable wallet discovery and signing for each chain you support.
  </Step>

  <Step title="Initialize">
    The client initializes automatically by default. Wait for initialization to
    complete before calling other SDK functions.
  </Step>

  <Step title="Build your UI">
    Use SDK functions to authenticate users, connect wallets, and sign
    transactions. You decide what the UI looks like — the SDK provides the
    logic.
  </Step>
</Steps>

## What you need to build

Because the SDK is headless, your app handles these screens:

* **Login** — collect an email/phone, trigger OTP or social auth, and verify the response
* **Wallet picker** — list available wallet providers and let the user choose one
* **MFA prompts** — prompt for TOTP codes or passkey verification when MFA is enabled
* **Step-up authentication** — re-verify identity before sensitive actions
* **Device registration** — verify the user's email when they sign in from an unrecognized device

<Tip>
  See [Authentication screens](/docs/javascript/authentication-methods/headless-authentication) for the full list with implementation guides.
</Tip>

## What the SDK handles

You call functions; the SDK manages the rest:

* **Authentication** — email OTP, SMS, social login, passkeys, external JWTs, and MFA
* **Wallet management** — embedded wallets (MPC-backed, user-owned) and external wallets (MetaMask, Phantom, etc.)
* **Transaction signing** — chain-specific signing, typed data, and message signing
* **Session management** — JWTs, token refresh, and logout
* **Events** — subscribe to auth, wallet, and session state changes with `onEvent()`
* **Multi-chain** — EVM, Solana, Bitcoin, Aptos, Sui, TON, Tron, and Starknet via extensions
* **Gasless transactions** — sponsor gas so users don't pay, on both EVM (via ZeroDev) and Solana
* **Fireblocks Flow** — accept crypto from any wallet or exchange and settle in a token and chain you choose

## Architecture

The SDK creates and manages a hidden iframe internally for WaaS/MPC key operations. You do **not** need to configure or install a separate iframe host package.

```
┌─────────────────────────────────────────────┐
│  Your web app (any framework or none)       │
│                                             │
│  @dynamic-labs-sdk/client                   │
│  @dynamic-labs-sdk/evm (or /solana, etc.)   │
│                                             │
│  ┌─────────────────────────────────────┐    │
│  │  Hidden iframe (MPC key operations) │    │
│  │  Managed internally by the SDK      │    │
│  └─────────────────────────────────────┘    │
└─────────────────────────────────────────────┘
```

## Use with React and React Native

For React (web), `@dynamic-labs-sdk/react-hooks` wraps client functions as hooks so components re-render when state changes. See the [React Hooks guide](/docs/javascript/reference/react-hooks-guide).

For React Native (Expo or bare), you add polyfills, native modules, and deep-link metadata — then auth, wallets, and signing match the web guides. See [React Native Setup](/docs/javascript/react-native/setup) for Expo vs bare details.

## Common mistakes

| Mistake                                                   | Fix                                                                                                                                       |
| :-------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
| Using `@dynamic-labs/sdk-react-core` without React        | Use `@dynamic-labs-sdk/client` instead                                                                                                    |
| Installing `@dynamic-labs/legacy-client` for React Native | That is the **legacy** RN SDK — use `@dynamic-labs-sdk/client` ([React Native Quickstart](/docs/javascript/reference/react-native-quickstart)) |
| Adding `@dynamic-labs/legacy-web-extension`               | Not needed — that package is for React Native on web                                                                                      |
| Loading SDK via `<script>` tag without a bundler          | Use Vite, webpack, or another bundler                                                                                                     |
| Expecting a built-in modal or wallet picker               | The JS SDK is headless — build your own UI                                                                                                |
| Calling `createDynamicClient` inside a render loop        | Create the client once at app startup                                                                                                     |

## What's next

<CardGroup cols={2}>
  <Card title="Wallets" icon="wallet" href="/docs/javascript/reference/wallets/build-wallet-picker">
    Build a wallet picker, connect wallets, and manage accounts.
  </Card>

  <Card title="Fireblocks Flow" icon="money-bill-transfer" href="/docs/javascript/reference/flow-getting-started">
    Accept crypto payments and settle in any token or chain.
  </Card>
</CardGroup>
