Local AWS Emulators for TypeScript Developers: A Practical Guide to Using kumo
typescriptawstestingdevtools

Local AWS Emulators for TypeScript Developers: A Practical Guide to Using kumo

AAvery Collins
2026-04-08
7 min read
Advertisement

Hands-on guide for TypeScript teams using kumo as a lightweight local AWS emulator: setup, SDK config, CI workflows, and persistence tips.

Local AWS Emulators for TypeScript Developers: A Practical Guide to Using kumo

kumo is a lightweight local AWS emulator that many TypeScript teams are adopting as a fast, CI-friendly localstack alternative. This hands-on walkthrough shows you how to set up kumo, configure both AWS SDK v3 and patterns for v4, design CI-friendly workflows, and choose between persistent and ephemeral state for integration tests.

Why use kumo as a local aws emulator?

kumo is built to be simple, fast, and easy to distribute. Key characteristics include:

  • Single binary with optional Docker support, making it trivial to run locally or in CI.
  • No authentication required by default, which simplifies CI testing where you don't want to manage credentials.
  • Optional data persistence via the KUMO_DATA_DIR environment variable, helping teams decide between ephemeral and persistent test environments.
  • Support for many AWS services developers commonly need for integration testing (S3, DynamoDB, SQS, SNS, Lambda, RDS, and more).

Quick local setup

You can run kumo either as a Docker container or as a local binary. For most TypeScript projects, Docker is convenient and CI-friendly.

Run kumo with Docker

Example Docker command to start kumo on the default port 4566:

docker run -d --name kumo -p 4566:4566 ghcr.io/sivchari/kumo:latest

If you want data persistence across restarts (useful for manual development sessions), mount a host directory and set the persistence env var:

docker run -d --name kumo -p 4566:4566 \
  -v /path/to/kumo-data:/data \
  -e KUMO_DATA_DIR=/data \
  ghcr.io/sivchari/kumo:latest

Run the single binary

Download and run the binary on Linux or macOS. Example:

curl -Lo kumo https://github.com/sivchari/kumo/releases/latest/download/kumo-linux-amd64 \
  && chmod +x kumo \
  ./kumo --address 0.0.0.0:4566

TypeScript: configuring the AWS SDK for kumo

The critical configuration for any AWS SDK client is overriding the endpoint to point to kumo, setting a region, and using dummy credentials when the SDK insists on them. Below are patterns for AWS SDK v3 and guidance for v4-style configuration.

AWS SDK for JavaScript v3

v3 uses modular clients. You usually set the endpoint in the client constructor. For S3, you also want forcePathStyle to true so the client won't try virtual-host style addressing locally.

import { S3Client } from '@aws-sdk/client-s3'

const s3 = new S3Client({
  region: 'us-west-2',
  endpoint: 'http://localhost:4566',
  forcePathStyle: true,
  credentials: { accessKeyId: 'kumo', secretAccessKey: 'kumo' }
})

// Use the client as usual

For DynamoDB and SQS the pattern is identical: pass endpoint, region and credentials to the client constructor.

import { DynamoDBClient } from '@aws-sdk/client-dynamodb'
const dynamo = new DynamoDBClient({ endpoint: 'http://localhost:4566', region: 'us-west-2', credentials: { accessKeyId: 'x', secretAccessKey: 'x' } })

SDK v4 configuration patterns (forward-compatible guidance)

While v4 of the AWS SDK for JavaScript evolves, the same principles apply: override endpoint resolution and supply a region and credentials. The exact constructor API may change, but your test wiring should follow these rules:

  • Provide an explicit endpoint or endpoint resolver that returns the kumo URL.
  • Keep credentials simple; kumo accepts requests without strict signing, but some SDKs want credentials objects—use static dummy values.
  • For S3-style services enforce path style addressing when supported by the client config.

In practice this means wrapping client construction in a helper so you can swap between real AWS and kumo with a single flag. Example helper shape:

// libs/awsClient.ts
import { S3Client } from '@aws-sdk/client-s3'

export function createS3Client({ useKumo }: { useKumo: boolean }) {
  if (useKumo) {
    return new S3Client({ region: 'us-west-2', endpoint: 'http://localhost:4566', forcePathStyle: true, credentials: { accessKeyId: 'x', secretAccessKey: 'x' } })
  }
  return new S3Client({ region: 'us-west-2' })
}

Integration tests: ephemeral vs persistent state

Choosing between ephemeral and persistent state for integration tests impacts flakiness, performance, and developer experience. Here are practical patterns.

Benefits: tests are deterministic, isolated, and fast to tear down. For CI, run kumo without mounting KUMO_DATA_DIR. Seed state at test setup and tear it down at the end.

  1. Start kumo in CI as a container with no volume mounts.
  2. Run a test setup script that creates S3 buckets, DynamoDB tables, queues, etc.
  3. Run tests that interact with kumo.
  4. Stop and remove the kumo container at job end; state is gone.

Example npm scripts and simple seed script pattern:

// package.json (partial)
{
  "scripts": {
    "kumo:up": "docker run -d --rm --name kumo -p 4566:4566 ghcr.io/sivchari/kumo:latest",
    "kumo:down": "docker stop kumo",
    "test:ci": "npm run kumo:up && node scripts/seed.js && jest --runInBand && npm run kumo:down"
  }
}

Persistent local state (developer convenience)

Benefits: quick iteration, fewer seed runs. Downsides: risk of stale state causing flaky tests and differences between local and CI behavior. If you choose persistence:

  • Mount a host directory into /data and set KUMO_DATA_DIR=/data.
  • Provide versioned seed/upgrade scripts to migrate data across kumo upgrades.
  • Occasionally reset the data directory during troubleshooting or when tests fail unexpectedly.

CI-friendly workflows

kumo is intentional about CI: no auth is required, and the single-binary or Docker images make it easy to run in ephemeral CI environments. Below is a sample GitHub Actions job that runs kumo as a service container and executes tests against it.

name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      kumo:
        image: ghcr.io/sivchari/kumo:latest
        ports:
          - 4566:4566
    steps:
      - uses: actions/checkout@v4
      - name: Install node
        uses: actions/setup-node@v4
        with:
          node-version: '18'
      - run: npm ci
      - run: node scripts/seed.js
      - run: npm test

Key points:

  • Use the service container to ensure kumo is available at localhost:4566 on the job runner.
  • Run a deterministic seed script to create resources needed by your tests.
  • Keep tests isolated and idempotent – design tests to clean up after themselves when possible.

Seeding tips and fast setups

Avoid slow, repetitive operations in test setup. Some concrete tips:

  • Batch-create resources where the emulator supports it.
  • Use smaller datasets for tests. You only need representative records, not full production dumps.
  • Cache compiled deployment artifacts (e.g., CloudFormation templates or SAM builds) in CI between jobs when possible.
  • If you use local persistence for development, create a script to snapshot and restore test fixtures quickly.

Practical troubleshooting

Common issues and quick fixes:

  • Port conflicts: ensure no other localstack or AWS emulator is using port 4566. Use a different port and update endpoint URLs if necessary.
  • Path vs virtual host addressing for S3: set forcePathStyle true in client config to avoid bucket name lookup issues locally.
  • Missing resources in tests: ensure your seed script runs before tests. Add retries with exponential backoff for eventual-consistency style resources.
  • State drift: if local tests fail but CI passes, reset your persistent kumo data directory to return to a clean state.

Example: full test lifecycle

Here is an end-to-end pattern many teams use in pipelines:

  1. Start kumo in CI without persistence.
  2. Run a deterministic seed script to create minimal required resources.
  3. Execute unit tests and fast integration tests in parallel.
  4. Run a small set of slow end-to-end tests against kumo in a dedicated job to keep feedback fast.
  5. Teardown kumo at the end of the job.

Where kumo fits in your dev toolbox

kumo is an excellent localstack alternative when you want a lighter-weight, faster emulator with straightforward behavior for CI. It pairs well with TypeScript projects that already use modular SDKs by keeping config centralized and test setups deterministic. If you enjoy reading about TypeScript tooling futures, check related perspectives on the site such as how new platforms affect TypeScript or developer tooling evolutions for broader context.

Practical checklist before adopting kumo

  • Identify which AWS services your tests require and confirm kumo supports them.
  • Create a single client factory in your codebase to toggle between real AWS and kumo easily.
  • Design seed scripts that are idempotent and fast.
  • Decide per-environment whether to mount KUMO_DATA_DIR for persistence or let tests be ephemeral.
  • Add CI jobs that run integration tests against kumo and fail fast on regressions.

Further reading and resources

To explore kumo repository details and supported services, visit the kumo project on GitHub. For broader TypeScript infrastructure patterns and migration guides, see other posts in this tooling pillar on the site.

With minimal configuration, kumo can speed up iteration cycles, make CI testing robust, and provide a predictable environment for integration tests. Try creating a small project that spins up kumo, seeds an S3 bucket and DynamoDB table, and runs a test against those resources — it's a low-effort way to validate the emulator for your workflows.

Advertisement

Related Topics

#typescript#aws#testing#devtools
A

Avery Collins

Senior Developer Advocate

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.

Advertisement
2026-04-09T19:07:02.182Z