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
Watch Mode (Recommended)
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:
Option 1: Automatic Release (Recommended)
-
Create a changeset:
pnpm changeset -
Commit the changeset:
git add .changeset git commit -m "Add changeset for new feature" -
Merge to main branch
-
Update versions:
pnpm changeset version # Apply changesets to bump versions -
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)
-
Create a hotfix branch:
git checkout -b hotfix/critical-fix -
Create changeset and update version:
pnpm changeset pnpm changeset version -
Commit and push:
git add . git commit -m "Release v1.2.3 - critical fix" git push origin hotfix/critical-fix -
Create and push a tag:
git tag v1.2.3 git push origin v1.2.3 -
Create a GitHub release:
gh release create v1.2.3 --title "Release v1.2.3" --generate-notesOr 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:
- Download the latest schema from the Restate server repo
- 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:
- Update and release the tour of Restate
- Update the TypeScript SDK and Tour version in the documentation
- Update and release the Node template generator
- 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 optionstsconfig.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:
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.