claude-code-sdk-ts

Fluent, chainable TypeScript SDK: configure models, enable tools, stream events, then fetch text, JSON, run details or token stats in one call via .asText() or .allowTools('Read', 'Write'). Multi-level logging plus live onMessage/onToolUse callbacks give deep, CLI-compatible observability.

206
Stars
27
Forks
TypeScript
Language
8/23/2026
Added
View on GitHubDownload ZIP

⚠️ Third-Party Software Notice

This skill is third-party open-source software developed and hosted independently on GitHub. SkillTip is an informational directory and does not control or maintain the underlying repository. Any security checks displayed are automated and limited in scope. Review the source code before installing.

Read the Terms of Service

Installation

Add to your Claude Code skills directory:

# Add to your Claude Code skills
git clone https://github.com/instantlyeasy/claude-code-sdk-ts

Getting Started

Guides for using skills like claude-code-sdk-ts.

Security Report

Verified

Last scanned: —

{
  "status": "PASSED",
  "issues": []
}

README.md

Claude Code SDK for TypeScript

npm version npm downloads License: MIT TypeScript Node.js Version

Unofficial TypeScript SDK for Claude Code - the powerful CLI tool for interacting with Claude.

✨ What's New in v0.4.0:

  • 🎬 Interactive streaming session with working visual typewriter effects
  • 🛡️ Typed error handling you catch with instanceof — no error categories, no wrappers
  • ⏱️ Timeouts and edit-acceptance that actually take effectwithTimeout() throws a real TimeoutError, acceptEdits() maps to the CLI's --permission-mode
  • 🔧 Production-ready examples that actually work as advertised

Note: For the classic async generator API, see Classic API Documentation.

Installation

npm install @instantlyeasy/claude-code-sdk-ts
# or
yarn add @instantlyeasy/claude-code-sdk-ts
# or  
pnpm add @instantlyeasy/claude-code-sdk-ts

Latest Version: v0.4.0 with enhanced features and working visual streaming!

Prerequisites:

  • Node.js 20 or later
  • Claude Code CLI installed (npm install -g @anthropic-ai/claude-code)

Quick Start

import { claude } from '@instantlyeasy/claude-code-sdk-ts';

// Simple query
const response = await claude()
  .query('Say "Hello World!"')
  .asText();

console.log(response); // "Hello World!"

Authentication

This SDK delegates all authentication to the Claude CLI:

# One-time setup - login with your Claude account
claude login

The SDK does not handle authentication directly and has no apiKey option. The CLI owns auth — either via claude login or an ANTHROPIC_API_KEY that the CLI reads from the environment. If you see authentication errors, authenticate using the Claude CLI first.

Core Features

🎯 Fluent API

Chain methods for clean, readable code:

const result = await claude()
  .withModel('sonnet')              // Choose model
  .allowTools('Read', 'Write')      // Configure permissions
  .acceptEdits()                    // Auto-accept file edits (--permission-mode acceptEdits)
  .inDirectory('/path/to/project')  // Set working directory
  .query('Refactor this code')     // Your prompt
  .asText();                       // Get response as text

acceptEdits() and skipPermissions() (full bypass) both map to the CLI's --permission-mode and take effect on the run.

📊 Response Parsing

Extract exactly what you need:

// Get plain text
const text = await claude()
  .query('Explain this concept')
  .asText();

// Parse JSON response
const data = await claude()
  .query('Return a JSON array of files')
  .asJSON<string[]>();

// Get the final result
const result = await claude()
  .query('Complete this task')
  .asResult();

// Analyze tool usage
const tools = await claude()
  .allowTools('Read', 'Grep')
  .query('Find all TODO comments')
  .asToolExecutions();

for (const execution of tools) {
  console.log(`${execution.tool}: ${execution.isError ? 'Failed' : 'Success'}`);
}

🔧 Tool Management

Fine-grained control over Claude's capabilities:

// Allow specific tools
await claude()
  .allowTools('Read', 'Grep', 'LS')
  .query('Analyze this codebase')
  .asText();

// Deny dangerous tools
await claude()
  .denyTools('Bash', 'Write')
  .query('Review this code')
  .asText();

// Read-only mode
await claude()
  .allowTools() // No arguments = deny the mutating tools (Write, Edit, Bash, ...), keep Read/Grep/Glob
  .query('Explain this architecture')
  .asText();

💬 Session Management

Maintain conversation context across queries. Get the session ID from the first real query's parser, then resume it on a new builder with withSessionId():

// First query — keep the parser so we can read its session ID
const firstQuery = claude()
  .withModel('sonnet')
  .skipPermissions()
  .query('Pick a random number between 1 and 100');

const response1 = await firstQuery.asText();
const sessionId = await firstQuery.getSessionId(); // resolved from the CLI's init message

// Resume that same conversation on a new builder
const response2 = await claude()
  .withModel('sonnet')
  .skipPermissions()
  .withSessionId(sessionId)
  .query('What number did you pick?')
  .asText();
// Claude remembers the number!

Don't call query('') just to obtain a session ID — an empty prompt starts a brand-new session, so the follow-up would have nothing to remember.

🚦 Cancellation Support

Cancel long-running operations:

import { claude, AbortError } from '@instantlyeasy/claude-code-sdk-ts';

const controller = new AbortController();

// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);

try {
  const response = await claude()
    .withSignal(controller.signal)
    .query('Long running task')
    .asText();
} catch (error) {
  if (error instanceof AbortError) {
    console.log('Query was cancelled');
  }
}

📝 Logging

Built-in logging with multiple implementations:

import { ConsoleLogger, LogLevel } from '@instantlyeasy/claude-code-sdk-ts';

const logger = new ConsoleLogger(LogLevel.DEBUG);

const response = await claude()
  .withLogger(logger)
  .query('Debug this issue')
  .asText();

// Also available: JSONLogger, MultiLogger, NullLogger

🎭 Event Handlers

React to events during execution:

await claude()
  .onMessage(msg => console.log('Message:', msg.type))
  .onAssistant(content => console.log('Claude sent', content.length, 'block(s)')) // content is ContentBlock[]
  .onToolUse(tool => console.log(`Using ${tool.name}...`))                        // tool is { name, input }
  .query('Perform analysis')
  .stream(async (message) => {
    // Handle streaming messages
  });

Environment Variables

The SDK automatically loads safe configuration from environment. The variables are namespaced so unrelated tooling can't flip them on by accident:

  • CLAUDE_SDK_DEBUG - Enable debug mode (values: true, 1, yes, on)
  • CLAUDE_SDK_VERBOSE - Enable verbose output
  • CLAUDE_SDK_LOG_LEVEL - Set log level (0-4)
  • NODE_ENV - Node environment

The generic DEBUG / VERBOSE / LOG_LEVEL variables are intentionally not read — they're set ubiquitously by CI and other tools. Use the CLAUDE_SDK_ variants.

⚠️ Important: The SDK never reads ANTHROPIC_API_KEY and has no apiKey option — authentication belongs to the Claude CLI (see above). See Environment Variables Documentation.

Error Handling

The SDK throws typed error classes. Catch the ones you care about with instanceof — each carries fields specific to what went wrong:

import {
  claude,
  RateLimitError,
  AuthenticationError,
  TimeoutError,
  AbortError,
  ProcessError
} from '@instantlyeasy/claude-code-sdk-ts';

try {
  await claude().query('Task').asText();
} catch (error) {
  if (error instanceof RateLimitError) {
    console.error(`Rate limited — retry after ${error.retryAfter}s`);
  } else if (error instanceof AuthenticationError) {
    console.error('Not authenticated. Run `claude login` and try again.');
  } else if (error instanceof TimeoutError) {
    console.error('The query timed out.');
  } else if (error instanceof AbortError) {
    console.error('The query was cancelled.');
  } else if (error instanceof ProcessError) {
    console.error(`Claude CLI exited with code ${error.exitCode}`);
  } else {
    throw error; // Unknown error — re-throw
  }
}

The classes fall into two families: the API/enhanced errors (RateLimitError, AuthenticationError, TimeoutError, NetworkError, ValidationError, ToolPermissionError) extend BaseSDKError, while the process/CLI errors (ProcessError, AbortError, CLINotFoundError, CLIConnectionError) extend ClaudeSDKError. Both ultimately extend the built-in Error, so a bare catch always works as a fallback.

Advanced Usage

Configuration Files & Roles

Load settings and define reusable roles from YAML or JSON.

withConfigFile() and withRolesFile() are async — they read and parse a file, so each returns a Promise. await the call on its own line before you chain the synchronous builder methods; you can't chain straight off the promise.

// withConfigFile applies MCP servers, global settings, and tool permissions
const builder = claude();
await builder.withConfigFile('./config/claude.yaml');

const result = await builder
  .query('Generate component')
  .asText();

Role System

Roles live in their own file (loaded with withRolesFile()) and provide reusable configurations with:

  • Model preference
  • Tool permissions (allowed / denied) and a permission mode
  • A prompting template with ${variable} substitution
  • A system prompt (delivered to the CLI via --append-system-prompt)
  • Inheritance via extends

Example roles file:

version: "1.0"

# Define reusable roles
roles:
  developer:
    model: sonnet
    permissions:
      mode: default
      tools:
        allowed: [Read, Write, Edit]
        denied: [Bash]
    promptingTemplate: |
      You are an expert ${language} developer using ${framework}.

  senior-developer:
    extends: developer          # Inherit from the developer role
    model: opus
    permissions:
      mode: acceptEdits
      tools:
        allowed: [TodoWrite]    # Additional tools
    systemPrompt: |
      Prioritize performance, readability, and test coverage.
// Load the roles file (async), then apply a role by name with template variables
const roleBuilder = claude();
await roleBuilder.withRolesFile('./roles.yaml');

const response = await roleBuilder
  .withRole('senior-developer', {
    language: 'TypeScript',
    framework: 'Next.js'
  })
  .query('Optimize this React component')
  .asText();

See Roles Documentation for complete details.

Production Features

Token Usage & Costs

// query() already returns the ResponseParser — just hold on to it
const parser = claude()
  .query('Complex task');

const usage = await parser.getUsage();
console.log('Tokens:', usage.totalTokens);
console.log('Cost: $', usage.totalCost);

Streaming

await claude()
  .query('Tell me a story')
  .stream(async (message) => {
    if (message.type === 'assistant') {
      // Stream complete messages (not individual tokens)
      console.log(message.content[0].text);
    }
  });

Custom Models & Timeouts

// withTimeout enforces a real deadline — it throws TimeoutError if the run exceeds it
const response = await claude()
  .withModel('claude-3-opus-20240229')
  .withTimeout(30000)
  .query('Complex analysis')
  .asText();

🚀 Enhanced Features (v0.4.0)

✨ Visual Token Streaming

Create typewriter effects and real-time response display:

import { claude, createTokenStream } from '@instantlyeasy/claude-code-sdk-ts';

// Collect response for controlled display
const messageGenerator = claude()
  .withModel('sonnet')
  .queryRaw('Write a story about AI');

const tokenStream = createTokenStream(messageGenerator);
const allTokens = [];

for await (const chunk of tokenStream.tokens()) {
  allTokens.push(chunk.token);
}

// Display with typewriter effect
const fullText = allTokens.join('');
for (const char of fullText) {
  process.stdout.write(char);
  await new Promise(resolve => setTimeout(resolve, 30));
}

🛡️ Advanced Error Handling

Handle specific error types with smart retry logic:

import { claude, detectErrorType, withRetry } from '@instantlyeasy/claude-code-sdk-ts';

// withRetry(fn, options) returns a WRAPPER function — it does not run fn itself.
// Call the wrapper to execute with retries.
const run = withRetry(
  () => claude().query('Complex task').asText(),
  {
    maxAttempts: 3,
    shouldRetry: (error) => {
      const errorType = detectErrorType(error.message);
      return ['network_error', 'timeout_error'].includes(errorType);
    }
  }
);

try {
  const result = await run(); // or, as one expression: await withRetry(fn, options)()
} catch (error) {
  const errorType = detectErrorType(error.message);
  console.log(`Failed with error type: ${errorType}`);
}

🎬 Interactive Streaming Session

NEW! Complete chat interface with visual streaming:

# Try the interactive streaming example
node examples/fluent-api/new-features/interactive-streaming.js

Features working character-by-character display, conversation history, speed control, and model switching!

Examples

Comprehensive examples are available in the examples directory:

Basic Examples

Advanced Features (new-features directory)

Core Examples

  • File Operations - Reading, writing, and analyzing code
  • Web Research - Using Claude's web capabilities
  • Interactive Sessions - Building conversational interfaces

Migration from Classic API

The SDK maintains full backward compatibility. The classic query() function still works:

import { query } from '@instantlyeasy/claude-code-sdk-ts';

for await (const message of query('Hello')) {
  // Classic async generator API
}

However, we recommend the fluent API for new projects. See Migration Guide.

API Reference

claude(): QueryBuilder

Creates a new query builder:

claude()
  .withModel(model: string)
  .allowTools(...tools: ToolName[])          // no args = read-only (denies mutating tools)
  .denyTools(...tools: ToolName[])
  .skipPermissions()                          // full bypass (--permission-mode bypassPermissions)
  .acceptEdits()                              // auto-accept edits (--permission-mode acceptEdits)
  .withTimeout(ms: number)                    // throws TimeoutError on expiry
  .inDirectory(path: string)
  .withSessionId(id: string)
  .withSignal(signal: AbortSignal)
  .withLogger(logger: Logger)
  .withConfigFile(path: string): Promise<this>   // async — await before chaining
  .withRolesFile(path: string): Promise<this>    // async — await before chaining
  .withRole(roleName: string)                    // overload 1: apply a loaded role by name
  .withRole(role: RoleDefinition, vars?: Record<string, string>)  // overload 2: inline definition
  .onMessage(handler: (msg: Message) => void)
  .onAssistant(handler: (content: ContentBlock[]) => void)
  .onToolUse(handler: (tool: { name: string; input: Record<string, unknown> }) => void)
  .query(prompt: string): ResponseParser

Response Parser Methods

  • asText() - Extract plain text
  • asJSON<T>() - Parse JSON response
  • asResult() - Get the final result message
  • asArray() - Get every message as an array
  • asToolExecutions() - Get tool execution details
  • findToolResults(name) - Find all results for a tool
  • findToolResult(name) - Get the first result for a tool
  • getUsage() - Get token usage stats
  • getSessionId() - Get the session ID (resolved from the init message)
  • stream(callback) - Stream messages
  • succeeded() - Whether the run finished without errors
  • getErrors() - Collect run/tool error messages
  • transform(fn) - Apply a custom transformer to the messages

Types

See TypeScript definitions for complete type information.

Changelog

See CHANGELOG.md for version history.

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

License

MIT © Daniel King & Claude

Links

Frequently Asked Questions

What is claude-code-sdk-ts?

claude-code-sdk-ts is an open-source cli tools skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by instantlyeasy. Fluent, chainable TypeScript SDK: configure models, enable tools, stream events, then fetch text, JSON, run details or token stats in one call via .asText() or .allowTools('Read', 'Write'). Multi-level logging plus live onMessage/onToolUse callbacks give deep, CLI-compatible observability. It has 206 GitHub stars.

Is claude-code-sdk-ts safe to use?

claude-code-sdk-ts returned warnings in SkillsLLM's automated security scan. It has no critical vulnerabilities, but review the flagged issues in the Security Report section before adding it to your workflow.

How do I install claude-code-sdk-ts?

Clone the repository with "git clone https://github.com/instantlyeasy/claude-code-sdk-ts" and add it to your Claude Code skills directory (see the Installation section above).

What programming language is claude-code-sdk-ts written in?

claude-code-sdk-ts is primarily written in TypeScript. It is open-source under instantlyeasy on GitHub, so you can review or fork the full source.

Are there alternatives to claude-code-sdk-ts?

Yes. SkillsLLM lists many other CLI Tools skills you can browse and compare side by side. Open the CLI Tools category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh claude-code-sdk-ts against similar tools.

Comments (0)

No comments yet. Be the first to share your thoughts!

ui-ux-pro-max-skill

by nextlevelbuilder

12

An AI skill that provides design intelligence for building professional UI/UX across multiple platforms.

119,92012,870Python
CLI Toolsai-skillsantigravity
View details

happy

by slopus

Mobile and Web client for Codex and Claude Code, with realtime voice, encryption and fully featured

23,4501,980TypeScript
CLI Tools
View details

claudecodeui

by siteboon

Use Claude Code, OpenCode, Cursor CLI, and Codex on mobile and web with CloudCLI (aka Claude Code UI). CloudCLI is a free open source webui/GUI that helps you manage your Claude Code session and projects remotely.

13,3941,866TypeScript
CLI Tools
View details

CRS-自建Claude Code镜像,一站式开源中转服务,让 Claude、OpenAI、Gemini、Droid 订阅统一接入,支持拼车共享,更高效分摊成本,原生工具无缝使用。

12,5471,869JavaScript
CLI Tools
View details

ccstatusline

by sirmalloc

🚀 Beautiful highly customizable statusline for Claude Code CLI with powerline support, themes, and more.

12,508545TypeScript
CLI Tools
View details

Developers Also Liked

Based on votes and bookmarks from developers who liked this skill

ECC

by affaan-m

10

The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

242,21936,702JavaScript
AI Agentsai-agentsanthropicclaude-code
View details
15

An agentic skills framework & software development methodology that works.

234,96620,863Shell
AI Agentsai-agentsbrainstorming
View details

n8n

by n8n-io

12

Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.

201,88160,308TypeScript
MCP Serversapisai-tools
View details

The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

185,94028,768JavaScript
AI Agentsai-agentsanthropicclaude-code
View details

cc-switch

by farion1231

3

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

128,8688,826Rust
AI Agentsclaude-codeai-tools
View details