Development Guidelines

May 20, 2026 · View on GitHub

Prerequisites

Project Structure

This is a monorepo containing multiple SDK packages:

packages/
├── libs/                           # SDK libraries (published to npm)
│   ├── restate-sdk/               # Main SDK
│   ├── restate-sdk-clients/       # Client library
│   ├── restate-sdk-core/          # Core functionality
│   ├── restate-sdk-cloudflare-workers/  # Cloudflare Workers support
│   ├── restate-sdk-testcontainers/     # Testing utilities
│   └── restate-sdk-zod/           # Zod integration
├── examples/                       # Example applications
│   ├── node/
│   ├── deno/
│   ├── bun/
│   ├── vercel/
│   ├── lambda/
│   ├── cloudflare/
└── tests/
    └── restate-e2e-services/      # E2E test services

Getting Started

Install Dependencies

pnpm install

Building the SDK

Build all library packages:

pnpm build

Build a specific package:

pnpm --filter @restatedev/restate-sdk build

If everything goes well, artifacts are created in each package's dist/ directory.

Development Workflow

For development, you can use watch mode which provides instant type checking without builds:

# Watch all lib packages (type checking only)
pnpm dev

# In another terminal, run the node example in dev mode (uses source directly)
pnpm examples:dev

# Or run a specific example
pnpm examples:dev bun

Testing Changes

Run all tests:

pnpm test

Run tests in watch mode (instant feedback, no build required):

pnpm test:watch

Run tests for a specific package:

pnpm --filter restate-e2e-services test

Code Quality

Run the formatter and linter:

pnpm format        # Format all files
pnpm lint          # Lint all packages

Before committing, run all checks (same as CI):

pnpm verify

This runs:

  • Format check
  • Lint
  • Type check
  • Build all packages
  • Tests
  • Export validation (ATTW)
  • API validation (API Extractor)

Running Examples

Development Mode (Uses Source)

Run examples without building:

pnpm examples:dev              # Run Node.js example (default)
pnpm examples:dev bun          # Run Bun example
pnpm examples:dev cloudflare   # Run Cloudflare example

Available examples: node (default), bun, deno, vercel, lambda, cloudflare

Production Mode (Uses Built Output)

Run examples with built packages:

pnpm build                     # Build packages first
pnpm examples:start            # Run node example with built packages
pnpm examples:start bun        # Run bun example with built packages

Package Management

Adding Dependencies

Add a dependency to a specific package:

pnpm --filter @restatedev/restate-sdk add <package-name>

Add a dev dependency to the root:

pnpm add -Dw <package-name>

Managing Monorepo Dependencies

Packages depend on each other using workspace protocol:

{
  "dependencies": {
    "@restatedev/restate-sdk-core": "workspace:*"
  }
}

For publishable packages that depend on other publishable packages, add them to external in tsdown.config.ts:

export default defineConfig({
  entry: ["src/index.ts"],
  external: ["@restatedev/restate-sdk-core"],
});

Common Commands

# Building
pnpm build              # Build lib packages only
pnpm build:all          # Build everything (libs + examples)
pnpm clean              # Clean build artifacts
pnpm clean:cache        # Clear turbo cache

# Development
pnpm dev                # Watch libs (type checking)
pnpm examples:dev       # Run node example (dev mode)
pnpm test:watch         # Test in watch mode

# Quality checks
pnpm verify             # Run all checks (CI equivalent)
pnpm lint               # Lint all packages
pnpm format             # Format all files
pnpm check:format       # Check formatting
pnpm check:types        # Type check
pnpm check:exports      # Verify package exports (ATTW)
pnpm check:api          # Check for forgotten type exports

# Package management
pnpm new                # Create a new package (interactive)
pnpm delete             # Delete a package (interactive)
pnpm add-entry          # Add custom entry point (interactive)

# Dependencies
pnpm deps:check         # Check for outdated dependencies
pnpm deps:update        # Update all dependencies

How It Works

This monorepo uses:

  • pnpm workspaces for package management
  • Turbo for task orchestration and caching
  • tsdown for building publishable packages (ESM + CJS + TypeScript declarations)
  • Vitest for testing
  • Changesets for version management

Dev vs Production Modes

Dev Mode (Fast):

  • Libs: Type checking only (tsc --noEmit --watch)
  • Examples: Use source files directly via path mappings
  • Tests: Vitest resolves libs from source
  • No build required! Changes reflect immediately

Production Mode (Validation):

  • Libs: Built to dist/ with tsdown
  • Examples: Use built output from dist/
  • Tests: Run against built packages
  • Validates actual published code

Releasing the Package

This repo uses two release workflows:

  1. Create a changeset:

    pnpm changeset
    
  2. Commit the changeset:

    git add .changeset
    git commit -m "Add changeset for new feature"
    
  3. Merge to main branch

  4. Update versions:

    pnpm changeset version  # Apply changesets to bump versions
    
  5. Push to main:

    • GitHub Actions automatically detects the version bump
    • Creates a git tag (e.g., v1.2.3)
    • Creates a GitHub release
    • Publishes packages to npm

Option 2: Manual Release (For Hotfixes)

  1. Create a hotfix branch:

    git checkout -b hotfix/critical-fix
    
  2. Create changeset and update version:

    pnpm changeset
    pnpm changeset version
    
  3. Commit and push:

    git add .
    git commit -m "Release v1.2.3 - critical fix"
    git push origin hotfix/critical-fix
    
  4. Create and push a tag:

    git tag v1.2.3
    git push origin v1.2.3
    
  5. Create a GitHub release:

    gh release create v1.2.3 --title "Release v1.2.3" --generate-notes
    

    Or via GitHub UI: Releases → Draft a new release → Select the tag → Publish release

When the release is published, GitHub Actions automatically publishes packages to npm.

Important: Never run pnpm release locally. Always let GitHub Actions handle publishing to ensure consistency and proper CI checks.

Re-generating the Discovery Manifest

The discovery manifest types in packages/libs/restate-sdk/src/endpoint/discovery.ts are auto-generated from the JSON Schema defined in the Restate server repository. These types define the structure that SDK endpoints return during service discovery.

To regenerate after a protocol update:

  1. Download the latest schema from the Restate server repo
  2. Run:
    npx --package=json-schema-to-typescript json2ts endpoint_manifest_schema.json packages/libs/restate-sdk/src/endpoint/discovery.ts
    

After Releasing

After creating a new SDK release, update dependent projects:

  1. Update and release the tour of Restate
  2. Update the TypeScript SDK and Tour version in the documentation
  3. Update and release the Node template generator
  4. Update the examples

Advanced Topics

Turbo Caching

Turbo automatically caches task outputs. Package scripts use turbo run --filter={.}... which:

  • Runs the command for the current package
  • Automatically builds dependencies first
  • Leverages Turbo's caching for speed

You can run commands from any package directory, and Turbo will handle dependencies:

cd packages/libs/restate-sdk
pnpm build          # Builds this package AND its dependencies
pnpm test           # Tests this package (builds dependencies first)

TypeScript Configuration

  • tsconfig.base.json - Shared compiler options
  • tsconfig.json - Extends base + path mappings (auto-generated for IDE support)
  • tsconfig.build.json - Clean builds (used by tsdown)

Path mappings are auto-generated when packages are created/deleted.

Private vs Public Packages

  • Public packages (in packages/libs/) are built with tsdown and published to npm
  • Private packages are source-only and get bundled into public packages automatically
  • Only non-private packages in packages/libs/ are published

Building the Shared Core (WASM)

The SDK includes Rust/WASM bindings in sdk-shared-core-wasm-bindings/. Most contributors don't need to rebuild this, but if you're modifying the shared core:

pnpm build:core

Prerequisites:

  • Rust (version specified in rust-toolchain.toml)
  • wasm-pack - install via cargo install wasm-pack

macOS Note: If you encounter C compiler errors (from the ring crate), install LLVM via Homebrew and set the compiler paths:

brew install llvm
CC=/opt/homebrew/opt/llvm/bin/clang AR=/opt/homebrew/opt/llvm/bin/llvm-ar pnpm build:core

For more detailed information about the monorepo structure and advanced features, see the template documentation.