| name | typescript-sdk-specialist |
| description | TypeScript SDK development with Node.js and browser support. Design SDK architecture, implement type-safe API clients, support ESM and CommonJS modules, and configure bundling for browsers. |
| allowed-tools | Bash(*) Read Write Edit Glob Grep WebFetch |
| metadata | {"author":"babysitter-sdk","version":"1.0.0","category":"multi-language-sdk","backlog-id":"SK-SDK-002"} |
| graph | {"domains":["domain:software-engineering"],"specializations":["specialization:sdk-platform-development"],"skillAreas":["skill-area:sdk-codegen","skill-area:api-clients-sdks"],"roles":["role:platform-engineer"],"topics":["topic:api-design","topic:developer-experience"]} |
typescript-sdk-specialist
You are typescript-sdk-specialist - a specialized skill for TypeScript SDK development, enabling creation of type-safe, tree-shakeable, and cross-platform API client libraries.
Overview
This skill enables AI-powered TypeScript SDK development including:
- Designing TypeScript SDK architecture
- Implementing type-safe API clients
- Supporting ESM and CommonJS dual modules
- Configuring bundling for browsers
- Implementing retry logic and error handling
- Adding request/response interceptors
- Supporting multiple runtimes (Node.js, Deno, Bun, browsers)
Prerequisites
- Node.js 18+ (or Bun/Deno)
- TypeScript 5.0+
- Package manager (npm, pnpm, or yarn)
- Build tools (tsup, esbuild, or Rollup)
- Testing framework (Vitest recommended)
Capabilities
1. SDK Architecture Design
Design a modular, type-safe SDK architecture:
import { BaseClient, ClientConfig } from './base';
import { UsersApi } from './api/users';
import { OrdersApi } from './api/orders';
import { AuthInterceptor } from './interceptors/auth';
import { RetryInterceptor } from './interceptors/retry';
export interface SDKConfig extends ClientConfig {
apiKey?: string;
accessToken?: string;
timeout?: number;
retries?: number;
baseUrl?: string;
}
export class MyServiceSDK {
private readonly client: BaseClient;
public readonly users: UsersApi;
public readonly orders: OrdersApi;
() {
. = ({
: config. ?? ,
: config. ?? ,
: [
(config),
({ : config. ?? })
]
});
. = (.);
. = (.);
}
(: , ?: <>): {
({ ...config, apiKey });
}
(: , ?: <>): {
({ ...config, accessToken });
}
}
2. Type-Safe API Client
Implement strongly-typed API methods:
import { BaseClient, RequestOptions } from '../base';
import {
User,
CreateUserRequest,
UpdateUserRequest,
ListUsersParams,
PaginatedResponse
} from '../models';
export class UsersApi {
constructor(private readonly client: BaseClient) {}
async get(id: string, options?: RequestOptions): Promise<User> {
return this.client.get<User>(`/users/${id}`, options);
}
(?: ): <<>> {
..<<>>(, {
: {
: params?. ?? ,
: params?. ?? ,
: params?.,
: params?.
}
});
}
(: ): <> {
..<>(, { : data });
}
(: , : ): <> {
..<>(, { : data });
}
(: ): <> {
..();
}
*(?: <, >): <> {
page = ;
hasMore = ;
(hasMore) {
response = .({ ...params, page });
( user response.) {
user;
}
hasMore = response.;
page++;
}
}
}
3. HTTP Client Base Implementation
Create a flexible HTTP client base:
import { ApiError, NetworkError, TimeoutError } from '../errors';
export interface RequestOptions {
params?: Record<string, string | number | boolean | undefined>;
headers?: Record<string, string>;
signal?: AbortSignal;
timeout?: number;
}
export interface RequestInterceptor {
onRequest?(config: RequestConfig): RequestConfig | Promise<RequestConfig>;
onResponse?<T>(response: T): T | Promise<T>;
onError?(error: Error): Error | Promise<Error>;
}
export class BaseClient {
private baseUrl: string;
private defaultTimeout: number;
private interceptors: RequestInterceptor[];
() {
. = config.;
. = config. ?? ;
. = config. ?? [];
}
get<T>(: , ?: ): <T> {
.<T>(, path, options);
}
post<T>(: , ?: & { ?: }): <T> {
.<T>(, path, options);
}
put<T>(: , ?: & { ?: }): <T> {
.<T>(, path, options);
}
patch<T>(: , ?: & { ?: }): <T> {
.<T>(, path, options);
}
<T = >(: , ?: ): <T> {
.<T>(, path, options);
}
request<T>(
: ,
: ,
?: & { ?: }
): <T> {
: = {
method,
: ,
: {
: ,
: ,
...options?.
},
: options?.,
: options?.,
: options?. ?? .,
: options?.
};
( interceptor .) {
(interceptor.) {
config = interceptor.(config);
}
}
{
response = .(config);
result = .<T>(response);
( interceptor .) {
(interceptor.) {
result = interceptor.(result);
}
}
result;
} (error) {
finalError = error ;
( interceptor .) {
(interceptor.) {
finalError = interceptor.(finalError);
}
}
finalError;
}
}
(: ): <> {
url = (config.);
(config.) {
( [key, value] .(config.)) {
(value !== ) {
url..(key, (value));
}
}
}
controller = ();
timeoutId = ( controller.(), config.);
{
response = (url.(), {
: config.,
: config.,
: config. ? .(config.) : ,
: config. ?? controller.
});
(timeoutId);
(!response.) {
.(response);
}
response;
} (error) {
(timeoutId);
(error && error. === ) {
();
}
(error ) {
error;
}
(, { : error });
}
}
parseResponse<T>(: ): <T> {
contentType = response..();
(contentType?.()) {
response.() <T>;
}
(response. === ) {
T;
}
response.() T;
}
(: ): <> {
: ;
{
body = response.();
} {
body = response.();
}
(
(body )?. ?? ,
response.,
(body )?.,
body
);
}
}
4. Dual ESM/CommonJS Package Configuration
Configure package.json for dual module support:
{
"name": "@company/myservice-sdk",
"version": "1.0.0",
"description": "TypeScript SDK for MyService API",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
5. Build Configuration with tsup
Configure tsup for optimal builds:
import { defineConfig } from 'tsup';
export default defineConfig({
entry: {
index: 'src/index.ts',
'models/index': 'src/models/index.ts'
},
format: ['cjs', 'esm'],
dts: true,
splitting: true,
treeshake: true,
clean: true,
minify: false,
sourcemap: true,
target: 'es2020',
outDir: 'dist',
external: [],
noExternal: [],
esbuildOptions(options, context) {
if (context.format === 'esm') {
options.platform = 'neutral';
options.conditions = ['browser', 'import', 'default'];
}
}
});
6. Error Handling
Implement comprehensive error types:
export class ApiError extends Error {
constructor(
message: string,
public readonly status: number,
public readonly code?: string,
public readonly body?: unknown
) {
super(message);
this.name = 'ApiError';
}
static isApiError(error: unknown): error is ApiError {
return error instanceof ApiError;
}
}
export class ValidationError extends ApiError {
constructor(
message: string,
public readonly errors: ValidationIssue[]
) {
super(message, 400, 'VALIDATION_ERROR');
this.name = 'ValidationError';
}
}
{
() {
(, , );
. = ;
}
}
{
() {
(, , );
. = ;
}
}
{
() {
(message, options);
. = ;
}
}
{
() {
(message);
. = ;
}
}
7. Retry Interceptor
Implement retry logic with exponential backoff:
import { RateLimitError, NetworkError, TimeoutError } from '../errors';
export interface RetryConfig {
maxRetries: number;
baseDelay?: number;
maxDelay?: number;
retryCondition?: (error: Error) => boolean;
}
export class RetryInterceptor implements RequestInterceptor {
private config: Required<RetryConfig>;
constructor(config: RetryConfig) {
this.config = {
maxRetries: config.maxRetries,
baseDelay: config.baseDelay ?? 1000,
maxDelay: config.maxDelay ?? 30000,
retryCondition: config.retryCondition ?? this.defaultRetryCondition
};
}
private defaultRetryCondition(error: ): {
(error ) ;
(error ) ;
(error ) ;
(error && error. >= ) ;
;
}
(: ): <> {
error;
}
}
withRetry<T>(
: <T>,
: <>
): <T> {
: ;
( attempt = ; attempt <= config.; attempt++) {
{
();
} (error) {
lastError = error ;
(!config.(lastError) || attempt === config.) {
lastError;
}
delay = .(
config. * .(, attempt) + .() * ,
config.
);
(lastError && lastError.) {
(lastError. * );
} {
(delay);
}
}
}
lastError!;
}
(): <> {
( (resolve, ms));
}
8. TypeScript Configuration
Optimal tsconfig.json for SDK development:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2020", "DOM"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
MCP Server Integration
This skill can leverage the following MCP servers:
| Server | Description | Installation |
|---|
| Claude Agent SDK | Official TypeScript SDK | GitHub |
| developer-kit | Skill building patterns | GitHub |
Best Practices
- Type safety first - Use strict TypeScript settings
- Tree-shakeable exports - Named exports over default
- Dual module support - ESM and CommonJS
- Comprehensive errors - Typed error classes
- Automatic retry - Exponential backoff with jitter
- Abort support - AbortController integration
- Minimal dependencies - Reduce bundle size
- Runtime agnostic - Support multiple JS runtimes
Process Integration
This skill integrates with the following processes:
multi-language-sdk-strategy.js - Language-specific patterns
sdk-architecture-design.js - Architecture decisions
sdk-testing-strategy.js - Testing patterns
package-distribution.js - npm publishing
Output Format
When executing operations, provide structured output:
{
"operation": "create-sdk",
"language": "typescript",
"features": {
"dualModule": true,
"browserSupport": true,
"typeSafety": "strict",
"treeshaking": true
},
"structure": {
"entryPoints": ["index.ts", "models/index.ts"],
"apiClasses": ["UsersApi", "OrdersApi"],
"models": 15,
"interceptors": ["AuthInterceptor"
Error Handling
- Provide typed error classes
- Include request correlation IDs
- Support error cause chaining
- Log actionable error messages
- Handle timeout gracefully
Constraints
- TypeScript 5.0+ required for modern features
- Browser support requires polyfills for older browsers
- Bundle size impacts download times
- Type generation can be slow for large APIs
- Some features may not work in all runtimes