
The Complete Guide to the Vercel AI SDK
A comprehensive guide to building AI-powered applications and agents with the Vercel AI SDK (v6) using TypeScript.
- 29 chapters
- Updated Aug 10, 2026
- 11 readers
What’s inside
- Navigation — Decision Matrix
- What the Vercel AI SDK Is and Why It Exists
- The Library Landscape & Getting Started
- Generating and Streaming Text
- Generating Structured Data
- Tool Calling
Contents
- 01The Complete Guide to the Vercel AI SDKp.1
- Building AI Applications and Agents with TypeScript — from First Token to Productionp.1
- Prefacep.1
- Table of Contentsp.1
- 02Navigation — Decision Matrixp.2
- 03What the Vercel AI SDK Is and Why It Existsp.3
- The problem: provider lock-in and fragmented APIsp.3
- What the AI SDK solvesp.3
- The two layers: AI SDK Core and AI SDK UIp.3
- Supported runtimes and frameworksp.3
- What's new in AI SDK 5 and 6p.3
- A unified message modelp.3
- Agents as a first-class conceptp.3
- The AI Gateway as the default model-access layerp.3
- Other v6 additions worth knowingp.3
- Key takeawaysp.3
- 04The Library Landscape & Getting Startedp.4
- The package ecosystemp.4
- The AI Gateway as the default providerp.4
- Installationp.4
- Environment and API-key setupp.4
- Your first `generateText` callp.4
- A minimal Next.js streaming routep.4
- Streaming from non-Next.js serversp.4
- How the pieces fit together and what to installp.4
- Key takeawaysp.4
- 05Generating and Streaming Textp.5
- `generateText` — single-shot generationp.5
- Prompt vs. messages, and system instructionsp.5
- Reading the resultp.5
- Multi-step generation with toolsp.5
- The `onEnd` callbackp.5
- `streamText` — incremental generationp.5
- `textStream` vs. the full `stream`p.5
- The `onChunk` and `onEnd` callbacksp.5
- Serving streams from a routep.5
- Backpressure, abort, and cancellationp.5
- Smoothing and transforming the streamp.5
- Handling long generationsp.5
- When to stream and when not top.5
- Key takeawaysp.5
- 06Generating Structured Datap.6
- Generating a structured objectp.6
- Output strategiesp.6
- `Output.object` — a typed recordp.6
- `Output.array` — a list of typed itemsp.6
- `Output.choice` — classificationp.6
- `Output.json` — unstructured but valid JSONp.6
- `Output.text` — the defaultp.6
- Improving accuracy: property descriptions, names, and reasoningp.6
- Streaming structured outputp.6
- Streaming objects to the client with `useObject`p.6
- Structured output via tools vs. `output`p.6
- Validating and repairing output, and error handlingp.6
- Key takeawaysp.6
- 07Tool Callingp.7
- What a tool isp.7
- Why descriptions and schemas matterp.7
- How the model decides to call a toolp.7
- Single vs. multi-step calls with `stopWhen`p.7
- Accessing tool calls and resultsp.7
- `onStepFinish`p.7
- Tool execution lifecycle callbacksp.7
- Response messagesp.7
- `toolChoice`p.7
- Tool execution optionsp.7
- Tool call IDp.7
- Messagesp.7
- Abort signalsp.7
- Tool contextp.7
- Streaming tool callsp.7
- Preliminary tool resultsp.7
- Dynamic toolsp.7
- Type-safe handling of mixed tool setsp.7
- Multi-modal tool resultsp.7
- Error handlingp.7
- With `generateText`p.7
- With `streamText`p.7
- Tool call repairp.7
- Tool execution approvalp.7
- How the manual flow worksp.7
- Dynamic approvalp.7
- `prepareStep`: per-step controlp.7
- Message compaction for long loopsp.7
- Active tools, tool order, and dynamic descriptionsp.7
- Provider-defined / server-side toolsp.7
- Extracting and typing toolsp.7
- Key takeawaysp.7
- 08Model Context Protocol (MCP) and Tool Contextp.8
- What MCP isp.8
- Initializing an MCP clientp.8
- HTTP transport (recommended)p.8
- SSE transportp.8
- Stdio transport (local servers only)p.8
- Using MCP toolsp.8
- Typed tool outputsp.8
- Using MCP tools with `generateText` / `streamText`p.8
- Closing the clientp.8
- Resources, prompts, and elicitationp.8
- MCP Appsp.8
- Runtime and tool contextp.8
- Runtime contextp.8
- Tool contextp.8
- Telemetry context filteringp.8
- Choosing the right contextp.8
- Best practices and security for remote toolsp.8
- Key takeawaysp.8
See all 29 parts
- 09Prompt Engineering, Settings, and Reasoningp.9
- Prompt vs. Messagesp.9
- The Message Formatp.9
- System Messagesp.9
- User Messages and Multi-Part Contentp.9
- Assistant Messagesp.9
- Tool Messagesp.9
- Prompt Engineering for the SDKp.9
- Prompts for Toolsp.9
- Schema Mapping Gotchasp.9
- Temperature for Tools and Structured Datap.9
- Debugging Promptsp.9
- Common Call Settingsp.9
- Language Model Call Optionsp.9
- Request Optionsp.9
- Provider Optionsp.9
- Reasoning Modelsp.9
- Controlling Reasoning Effortp.9
- Extracting Reasoningp.9
- Precedence: `reasoning` vs. `providerOptions`p.9
- Migrating from `providerOptions`p.9
- Key takeawaysp.9
- 10Embeddings and Rerankingp.10
- Embedding a Single Valuep.10
- Embedding Many Valuesp.10
- Token Usagep.10
- Cosine Similarityp.10
- Settingsp.10
- Provider Optionsp.10
- Parallel Requests with `maxParallelCalls`p.10
- Retries, Abort Signals, and Headersp.10
- Embedding Middlewarep.10
- Embedding Providers and Modelsp.10
- Building a Semantic-Search / RAG Embedding Pipelinep.10
- Rerankingp.10
- Reranking Documentsp.10
- The Result Objectp.10
- Reranking Object Documentsp.10
- Settingsp.10
- Reranking Providers and Modelsp.10
- When to Rerank in RAGp.10
- Key takeawaysp.10
- 11Multimodal Generation: Images, Speech, Transcription, Video, and Filesp.11
- Image Generationp.11
- Size and Aspect Ratiop.11
- Generating Multiple Imagesp.11
- Seed, Provider Options, and Metadatap.11
- Error Handlingp.11
- Generating Images with Language Modelsp.11
- Realtime (Experimental)p.11
- Setup Endpointp.11
- Client Sessionp.11
- Transcription (Experimental)p.11
- Settings and Downloadsp.11
- Speech (Experimental)p.11
- Video Generation (Experimental)p.11
- Video Settingsp.11
- Image-to-Videop.11
- Timeouts and Pollingp.11
- Metadata and Errorsp.11
- File Uploadsp.11
- Supported File Types and Optionsp.11
- How Provider References Workp.11
- Multi-Provider Usagep.11
- Key takeawaysp.11
- 12Provider and Model Managementp.12
- Why centralize provider configurationp.12
- How provider packages workp.12
- Custom providers with `customProvider`p.12
- Pre-configuring model settingsp.12
- Model name aliasesp.12
- Limiting available modelsp.12
- Attaching `files` and `skills` interfacesp.12
- The provider registryp.12
- Setup and custom separatorsp.12
- Accessing models from the registryp.12
- Combining custom providers, the registry, and middlewarep.12
- The AI Gateway as the default providerp.12
- Customizing the global providerp.12
- Choosing and swapping models cleanlyp.12
- Key takeawaysp.12
- 13Language Model Middlewarep.13
- Applying middleware with `wrapLanguageModel`p.13
- Composing multiple middlewaresp.13
- Built-in middlewarep.13
- Extract reasoningp.13
- Extract JSONp.13
- Simulate streamingp.13
- Default settingsp.13
- Add tool input examplesp.13
- The `LanguageModelMiddleware` interfacep.13
- Logging middlewarep.13
- Caching middlewarep.13
- RAG injection middlewarep.13
- Guardrails middlewarep.13
- Per-request custom metadatap.13
- Community middlewarep.13
- Skill Uploadsp.13
- Multi-provider skillsp.13
- Key takeawaysp.13
- 14Error Handling, Testing, Telemetry, and DevToolsp.14
- The error modelp.14
- Handling regular errorsp.14
- Handling streaming errorsp.14
- Simple streamsp.14
- Full streams with error partsp.14
- Handling stream abortsp.14
- Retries and `maxRetries`p.14
- Testing with mock providersp.14
- Mocking `generateText`p.14
- Mocking `streamText`p.14
- Simulating UI message stream responsesp.14
- Telemetryp.14
- Enabling telemetryp.14
- Metadata: `functionId`, `runtimeContext`, and recordingp.14
- Spans and conventionsp.14
- Telemetry integrationsp.14
- DevToolsp.14
- Event callbacks as cross-cutting observability hooksp.14
- The `generateText` / `streamText` lifecyclep.14
- `embed` / `embedMany` and `rerank` callbacksp.14
- Callbacks never break your flowp.14
- Callbacks vs. telemetry integrationsp.14
- Key takeawaysp.14
- 15Agent Fundamentals: The Agent Loop and Loop Controlp.15
- What Is an Agent in the SDK?p.15
- Why Use the ToolLoopAgent Class?p.15
- Creating an Agentp.15
- Configuration Optionsp.15
- Model and System Instructionsp.15
- Toolsp.15
- Context and Agent Statep.15
- Tool Choicep.15
- Structured Outputp.15
- Define Agent Behavior with System Instructionsp.15
- Using an Agentp.15
- Generate Textp.15
- Stream Textp.15
- Respond to UI Messagesp.15
- Lifecycle Callbacksp.15
- End-to-End Type Safetyp.15
- The Agent Loopp.15
- Loop Controlp.15
- Stop Conditions with stopWhenp.15
- Custom Stop Conditionsp.15
- prepareStep: Adjust Model, Messages, and Tools Per Stepp.15
- Controlling Context Growthp.15
- Forced Tool Callingp.15
- Manual Loop Controlp.15
- Configuring Call Optionsp.15
- Key Takeawaysp.15
- 16Workflow Patternsp.16
- Deterministic vs. Agentic Controlp.16
- Sequential Processing (Chains)p.16
- Routing (Classification)p.16
- Parallel Processingp.16
- Orchestrator-Workerp.16
- Evaluator-Optimizerp.16
- When to Hand Control to the Model vs. Encode It Yourselfp.16
- Key Takeawaysp.16
- 17Advanced Agents: Memory, Subagents, Approvals, Skills, and DurableAgent (Workflow DevKit)p.17
- Memoryp.17
- Provider-Defined Toolsp.17
- Memory Providersp.17
- Building a Custom Memory Toolp.17
- Subagentsp.17
- Tool Approvals (Human-in-the-Loop)p.17
- Compacting Agent Contextp.17
- Skills: Adding Specialized Knowledge on Demandp.17
- DurableAgent: Durable, Resumable Agents (Workflow DevKit, v6)p.17
- WorkflowChatTransportp.17
- Key Takeawaysp.17
- 18Building Chatbots with useChatp.18
- 16.1 The minimal chatbotp.18
- 16.2 The UIMessage model and rendering partsp.18
- 16.3 The UIMessage-vs-ModelMessage split on the serverp.18
- 16.4 Status: driving the UI through the request lifecyclep.18
- 16.5 Stopping and regeneratingp.18
- 16.6 Error handlingp.18
- 16.7 Directly modifying messagesp.18
- 16.8 Event callbacksp.18
- 16.9 Controlling the request: headers, body, and credentialsp.18
- 16.10 Sending custom body fields per requestp.18
- 16.11 Message metadatap.18
- 16.12 Throttling UI updatesp.18
- Key takeawaysp.18
- 19Persistence, Resumable Streams, and Transportsp.19
- 17.1 The persistence modelp.19
- 17.2 Starting and loading a chatp.19
- 17.3 Saving on the serverp.19
- 17.4 Message IDs and server-side generationp.19
- 17.5 Sending only the last messagep.19
- 17.6 Handling client disconnectsp.19
- 17.7 Resumable streamsp.19
- Client: enabling resumep.19
- Server: the POST handler creates the streamp.19
- Server: the GET handler resumes the streamp.19
- 17.8 Stopping a resumable streamp.19
- 17.9 Transportsp.19
- Configuring DefaultChatTransportp.19
- Trigger-based routingp.19
- Other transportsp.19
- Key takeawaysp.19
- 20Tool Usage and Human-in-the-Loop in the UIp.20
- 18.1 The three tool execution patternsp.20
- 18.2 Tool part statesp.20
- 18.3 Rendering tool partsp.20
- 18.4 Streaming tool inputsp.20
- 18.5 Client-side tool executionp.20
- 18.6 Human-in-the-loop: confirmation toolsp.20
- 18.7 Human-in-the-loop: server-side tool approvalp.20
- 18.8 Dynamic tools and step boundariesp.20
- 18.9 Server-side multi-step and error surfacingp.20
- Key takeawaysp.20
- 21Generative User Interfacesp.21
- How Generative UI Worksp.21
- Building a Generative UI Chat Interfacep.21
- Defining a Toolp.21
- The Display Componentp.21
- Mapping Tool Parts to Componentsp.21
- Adding More Tools and Componentsp.21
- Streaming Structured UI State with Data Partsp.21
- Rendering Persistent Data Partsp.21
- Transient Data Parts via onDatap.21
- Tool Parts vs Data Partsp.21
- Key takeawaysp.21
- 22Completion, Object Generation, and Custom Data Streamingp.22
- useCompletion: Single-Prompt Completionsp.22
- States, Cancellation, and Throttlingp.22
- Event Callbacks and Request Optionsp.22
- useObject: Streaming Structured Objectsp.22
- Enum Output Modep.22
- Loading, Stop, Error, and Callbacksp.22
- Streaming Custom Datap.22
- The Three Kinds of Streamable Datap.22
- Processing Data on the Clientp.22
- Message Metadata vs Data Partsp.22
- UI Error Handling and Warningsp.22
- Warningsp.22
- Errorsp.22
- Reading UI Message Streamsp.22
- Message Metadatap.22
- Key takeawaysp.22
- 23Framework and Server Integrationp.23
- The Two Families of Response Helpersp.23
- Next.js Route Handlers (Recap)p.23
- Edge vs Node Runtimep.23
- Node.js HTTP Serverp.23
- Expressp.23
- Honop.23
- Fastifyp.23
- Nest.jsp.23
- Streaming Considerations Across Frameworksp.23
- Choosing a Patternp.23
- Key takeawaysp.23
- 24The Vercel AI Gatewayp.24
- Why route through a Gatewayp.24
- Basic usage: plain model stringsp.24
- The `gateway` provider instancep.24
- Authentication: API key, access token, or OIDCp.24
- The model id format and model routingp.24
- Automatic fallbacks and failoverp.24
- Per-provider options through the Gatewayp.24
- Provider-executed and Gateway-executed toolsp.24
- Reranking through the Gatewayp.24
- Cost and usage monitoringp.24
- Budgets, quotas, and compliance routingp.24
- Bring Your Own Key (BYOK)p.24
- Discovering available modelsp.24
- Key takeawaysp.24
- 25Provider Deep-Divesp.25
- How provider packages are structuredp.25
- OpenAIp.25
- Anthropicp.25
- Google Generative AI and Vertexp.25
- Amazon Bedrockp.25
- Groqp.25
- Mistralp.25
- xAI Grokp.25
- DeepSeekp.25
- Together.ai, Fireworks, Cohere, and the open-model platformsp.25
- The OpenAI-Compatible providerp.25
- Survey: other providers at a glancep.25
- Key takeawaysp.25
- 26Production Best Practicesp.26
- 24.1 Architecture and configurationp.26
- 24.2 Streaming and UXp.26
- 24.3 Tool calling and agentsp.26
- 24.4 Structured outputp.26
- 24.5 Cost and performancep.26
- 24.6 Securityp.26
- 24.7 Reliability and observabilityp.26
- 24.8 Production deploymentp.26
- Key takeawaysp.26
- 27End-to-End Projectsp.27
- Project 1 — RAG Chatbotp.27
- Goalp.27
- Architecturep.27
- The schema and indexp.27
- Chunking and embeddingp.27
- Retrieval with cosine similarityp.27
- The chat route with retrieval toolsp.27
- Rendering tool activity in the UIp.27
- Gotchasp.27
- Project 2 — Natural-Language-to-SQL over Postgresp.27
- Goalp.27
- Architecturep.27
- Generating safe SQL with structured outputp.27
- Explaining the queryp.27
- Charting without round-tripping the datap.27
- Wiring the frontendp.27
- Gotchasp.27
- Project 3 — Multi-Modal Agentp.27
- Goalp.27
- Architecturep.27
- The route handlerp.27
- Uploading and sending filesp.27
- Rendering mixed contentp.27
- Swapping providers — and adding toolsp.27
- Gotchasp.27
- Project 4 — Slack AI Agentp.27
- Goalp.27
- Architecturep.27
- The event handlerp.27
- The agent loopp.27
- Status, mentions, and threadsp.27
- AI Gateway and deploymentp.27
- Gotchasp.27
- Project 5 — Computer Usep.27
- Goalp.27
- Architecturep.27
- Defining the Computer Toolp.27
- Running it, and the agentic loopp.27
- Combining the three toolsp.27
- Gotchasp.27
- Key takeawaysp.27
- 28Appendix A — Error Referencep.28
- Quick referencep.28
- Call and transport errorsp.28
- AI_APICallErrorp.28
- AI_RetryErrorp.28
- AI_EmptyResponseBodyErrorp.28
- AI_DownloadErrorp.28
- AI_LoadAPIKeyErrorp.28
- Generation result errorsp.28
- AI_NoObjectGeneratedErrorp.28
- AI_NoOutputGeneratedErrorp.28
- AI_NoSpeechGeneratedErrorp.28
- AI_NoTranscriptGeneratedErrorp.28
- AI_NoImageGeneratedErrorp.28
- AI_NoVideoGeneratedErrorp.28
- Tool-calling errorsp.28
- AI_NoSuchToolErrorp.28
- AI_InvalidToolInputErrorp.28
- ToolCallRepairErrorp.28
- AI_ToolCallNotFoundForApprovalErrorp.28
- AI_InvalidToolApprovalErrorp.28
- Configuration and lookup errorsp.28
- AI_NoSuchModelErrorp.28
- AI_NoSuchProviderErrorp.28
- AI_UnsupportedFunctionalityErrorp.28
- Validation and parsing errorsp.28
- AI_InvalidPromptErrorp.28
- AI_TypeValidationErrorp.28
- AI_JSONParseErrorp.28
- Streaming and message errorsp.28
- AI_UIMessageStreamErrorp.28
- AI_MessageConversionErrorp.28
- Embedding errorsp.28
- AI_TooManyEmbeddingValuesForCallErrorp.28
- Key takeawaysp.28
- 29Appendix B — Migration Guide (v3 → v6)p.29
- B.1 v3 → v4p.29
- B.2 v4 → v5 — the big rebuildp.29
- B.3 v5 → v6 — renames and new defaultsp.29
- B.4 A pragmatic upgrade checklistp.29
- Key takeawaysp.29
From the first page
> Load this book when: > - You are building an AI feature in TypeScript/JavaScript with the Vercel AI SDK (ai package) — chat, text/structured generation, tool calling, agents, embeddings, or multimodal I/O. > - You are deciding between provider SDKs and need one provider-agnostic API, or routing models through the Vercel AI Gateway. > - You are building agents (the agent loop, ToolLoopAgent, loop control, memory, subagents, approvals, durable workflows). > - You are building a streaming chat or generative UI with useChat / useObject / useCompletion (React, Vue, Svelte) and a Next.js / Express / Hono / Fastify / Nest.js backend. > - You are integrating MCP servers, structured output (Output.), middleware, telemetry, or testing AI code. > - You are migrating an existing app across AI SDK v3 → v6 and need the renames and breaking-change checklist. > > Targets the AI SDK 6 generation of the ai package (current API names throughout).
The Vercel AI SDK is a provider-agnostic TypeScript toolkit for building AI-powered applications and agents. It runs everywhere modern JavaScript runs — React, Next.js, Vue, Svelte, Node.js, and the edge — and it has become one of the most widely used ways to talk to large language models from JavaScript, with millions of weekly downloads.
Its promise is simple: write your AI logic once, against one unified API, and swap models and providers with a string. Underneath that promise is a deep, fast-moving toolkit covering text and structured generation, tool calling, autonomous agents, multimodal input and output, streaming chat interfaces, and a model gateway. This book is the map.
Read a preview
Who this book is for. TypeScript and JavaScript developers building real AI features: chatbots, RAG systems, structured-extraction pipelines, and autonomous agents. You should be comfortable with async/await, modern ES modules, and — for the UI chapters — React and Next.js. You do not need prior machine-learning experience.
What it covers. This book targets the current generation of the SDK (versions 5 and 6, the ai package). It is built directly on the official documentation and supplemented with production best practices, common pitfalls, and version-migration notes drawn from Vercel's engineering guidance and the wider community. Where behavior is version-specific, the text says so.
How to read it. The book is organized in six parts that move from fundamentals to production:
- Part I — Foundations orients you: what the SDK is, how the packages fit together, and your first running call. - Part II — AI SDK Core is the engine room: text and structured generation, tool calling, MCP, prompts and settings, embeddings, multimodal I/O, providers, middleware, and operations. - Part III — Building Agents covers the agent loop, loop control, workflow patterns, and advanced agents (memory, subagents, approvals, skills, durable workflows). - Part IV — AI SDK UI builds the front end: useChat, persistence and resumable streams, tool UIs, generative interfaces, and framework integration. - Part V — Providers & the AI Gateway covers the Gateway as your default abstraction and deep-dives the major providers. - Part VI — Production & Projects brings it together with a best-practices chapter and five end-to-end builds, followed by an error reference and a migration guide.
Read Parts I and II in order if you are new to the SDK; after that, each chapter stands on its own and cross-references the others by name. Every code example is grounded in the current API — no invented functions, no aspirational pseudo-code.
A note on versions: the SDK moves fast. Several APIs were renamed between v5 and v6 (for example generateObject gave way to Output.object, and the agent class became ToolLoopAgent). This book uses the current names throughout and flags the important changes in Appendix B.
> Currency & scope. Last verified: 2026-06-14, against AI SDK 6 (latest [email protected] at time of writing). The ai package moves fast; treat any specific API name, default, model id, or providerOptions value as accurate for the v6 line and re-verify against ai-sdk.dev before relying on it past a major version bump. Refresh cadence: review on every AI SDK major release and at least quarterly (fast-moving / tactical surface — Writing Books for AI Agents, RULE 14.4). Audience: public marketplace reference book; built on and attributed to Vercel's official AI SDK documentation and the AI SDK 6 announcement. > > Companion: authored to the standards in Writing Books for AI Agents (CandleKeep ID cmqdpn0oo01e4rv0z0kitugn2, Ch 14 currency, Ch 17 self-audit). Version horizon: v6 ([email protected]) is the current stable line; an AI SDK v7 line is in active docs (native WorkflowAgent, @ai-sdk/workflow). Re-audit this book against v7 on its stable release before treating any v6-specific durable-agent or message API as current.
Part I — Foundations - Chapter 1 — What the Vercel AI SDK Is and Why It Exists - Chapter 2 — The Library Landscape & Getting Started
Part II — AI SDK Core - Chapter 3 — Generating and Streaming Text - Chapter 4 — Generating Structured Data - Chapter 5 — Tool Calling - Chapter 6 — Model Context Protocol (MCP) and Tool Context - Chapter 7 — Prompt Engineering, Settings, and Reasoning - Chapter 8 — Embeddings and Reranking - Chapter 9 — Multimodal Generation: Images, Speech, Transcription, Video, and Files - Chapter 10 — Provider and Model Management - Chapter 11 — Language Model Middleware - Chapter 12 — Error Handling, Testing, Telemetry, and DevTools
Part III — Building Agents - Chapter 13 — Agent Fundamentals: The Agent Loop and Loop Control - Chapter 14 — Workflow Patterns - Chapter 15 — Advanced Agents: Memory, Subagents, Approvals, Skills, and DurableAgent (Workflow DevKit)
Part IV — AI SDK UI - Chapter 16 — Building Chatbots with useChat - Chapter 17 — Persistence, Resumable Streams, and Transports - Chapter 18 — Tool Usage and Human-in-the-Loop in the UI - Chapter 19 — Generative User Interfaces - Chapter 20 — Completion, Object Generation, and Custom Data Streaming - Chapter 21 — Framework and Server Integration
Part V — Providers & the AI Gateway - Chapter 22 — The Vercel AI Gateway - Chapter 23 — Provider Deep-Dives
Part VI — Production & Projects - Chapter 24 — Production Best Practices - Chapter 25 — End-to-End Projects
Appendices - Appendix A — Error Reference - Appendix B — Migration Guide (v3 → v6)
Add this book to your library to keep reading.




