nimbus

module
v0.4.26 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 27, 2026 License: MIT

README

Nimbus

Nimbus

A free, open-source AWS emulator for local development. Forever.

Nimbus runs S3, SQS, DynamoDB, Secrets Manager, SSM Parameter Store, SES, Lambda, and API Gateway locally in a single Docker container on port 4566 — a drop-in replacement for LocalStack Community Edition. No account. No auth token. No commercial restrictions. MIT licensed.


Why Nimbus?

LocalStack built something genuinely useful on the backs of open-source contributors, then locked it behind a paywall. Nimbus exists because local AWS emulation should be free for everyone — individual developers, startups, enterprises, and open-source projects alike.

"Free for everyone, forever."


Quickstart

docker run -p 4566:4566 ghcr.io/nimbus-local/nimbus:latest

Or with Docker Compose:

services:
  nimbus:
    image: ghcr.io/nimbus-local/nimbus:latest
    ports:
      - "4566:4566"
    environment:
      AWS_DEFAULT_REGION: us-east-1
    volumes:
      - nimbus_data:/var/lib/nimbus

  dynamodb-local:
    image: amazon/dynamodb-local:latest
    command: "-jar DynamoDBLocal.jar -sharedDb -dbPath /data"
    volumes:
      - dynamodb_data:/data

volumes:
  nimbus_data:
  dynamodb_data:

Services

Service Status Detection Docs
S3 ✅ Core catch-all (path / virtual-hosted) PutObject, GetObject, DeleteObject, ListObjectsV2, HeadObject, CreateBucket, DeleteBucket, multipart uploads, presigned URLs
S3 Control ✅ Core x-amz-account-id header or /v20180820/ path prefix Account-level tag and public access block stubs — accepts Pulumi/TF provider calls as no-ops
SQS ✅ Core Action param or AmazonSQS.* target CreateQueue, SendMessage, ReceiveMessage, DeleteMessage, PurgeQueue, visibility timeout
DynamoDB ✅ Full DynamoDB_* target Proxied to DynamoDB Local — full parity
Secrets Manager ✅ Core secretsmanager.* target CreateSecret, GetSecretValue, PutSecretValue, UpdateSecret, DeleteSecret, ListSecrets, DescribeSecret, RestoreSecret
SSM Parameter Store ✅ Core AmazonSSM.* target PutParameter, GetParameter, GetParameters, GetParametersByPath, DeleteParameter, DescribeParameters — String, StringList, SecureString, path hierarchy, versioning
SES ✅ Core AmazonSimpleEmailService.* target or /v2/email/ path SendEmail (v1+v2), SendRawEmail, VerifyEmailIdentity, ListIdentities — emails captured in memory, never sent
Lambda ✅ Core /2015-03-31/ path prefix Functions (CRUD, versions, publish), invocations, aliases, permissions, event source mappings, concurrency, layers, code signing, function URLs, event invoke config, runtime & recursion settings, tags
AppSync ✅ Core /v1/apis path prefix (mgmt); /_appsync/{id}/graphql or {id}.appsync-api.{region}.nimbus.local (exec) GraphQL API (CRUD), schema upload, Lambda/NONE data sources, resolvers, API keys, tags — management plane + GraphQL execution (Lambda invocation, basic VTL: $context.arguments, $context.result, $util.toJson)
API Gateway ✅ Core /restapis (REST v1), /apis (HTTP v2 + WebSocket) REST API: resources, methods, integrations (AWS_PROXY + MOCK), stages. HTTP API: routes, integrations (AWS_PROXY, payload format v1+v2), stages, $default catch-all. WebSocket API: control plane (CRUD), $connect/$disconnect/$default routes, routeSelectionExpression — data plane (WS upgrade + Lambda dispatch) in progress
ECR ✅ Core AmazonEC2ContainerRegistry_V20150921.* target or /v2/ path CreateRepository, GetAuthorizationToken, ListImages, BatchDeleteImage, BatchGetImage + full Docker V2 registry (push/pull blobs and manifests)
ECS ✅ Core AmazonEC2ContainerServiceV20141113.* target Clusters (CRUD + settings), task definitions (register/deregister/describe/list), tasks (run/stop/describe/list), services (CRUD) — tasks simulated as immediately RUNNING; containerInsights clusters publish performance events to CloudWatch Logs
EC2 (VPC) ✅ Core POST / form-encoded body VPC, Subnet, Internet Gateway, Security Group (create/delete + default), Route Table, Route, RouteTableAssociation, Tags, DescribeAvailabilityZones — full lifecycle for Pulumi NewVpc construct
IAM ✅ Core form-encoded body, Version=2010-05-08 CreateRole/GetRole/DeleteRole/ListRoles, policy attachments, inline policies, managed policies, instance profiles; no enforcement — AssumeRole always succeeds
CloudWatch Logs ✅ Core Logs_20140328.* target CreateLogGroup/DeleteLogGroup/DescribeLogGroups, CreateLogStream/DescribeLogStreams, PutLogEvents, GetLogEvents/FilterLogEvents with JSON, space-delimited, and term filter patterns
KMS ✅ Core TrentService.* target CreateKey, Encrypt/Decrypt (real AES-256-GCM), GenerateDataKey, ReEncrypt, aliases, tags, key lifecycle (enable/disable/schedule-deletion)
SNS ✅ Core AmazonSimpleNotificationService.* target or Action param CreateTopic, Subscribe (all protocols, auto-confirmed), Publish, PublishBatch — messages captured in memory, never delivered
EventBridge ✅ Core AmazonEventBridge.* target PutEvents (captured in memory), event buses (CRUD), rules (CRUD, enable/disable), targets (put/remove/list)
EventBridge Scheduler ✅ Core /schedules or /schedule-groups bare path prefix Schedule groups (CRUD), schedules (CRUD), tags — expressions stored; firing added in Part 2
CloudFront ✅ Core /2020-05-31/ path prefix Distribution CRUD — localhost-based DomainName, status always Deployed, ETag per distribution
ALB ✅ Core form-encoded body, Version=2015-12-01 Load balancer, target group, listener, and rule CRUD — localhost-based DNSName, state always active; listeners start a real reverse proxy that routes requests to registered IP targets
RDS / Aurora ✅ Core form-encoded body, Version=2014-10-31 Subnet group, parameter group, cluster, and instance CRUD — cluster endpoint resolves to a real Postgres sidecar; status always available; Describe Filters supported (db-instance-id, db-cluster-id); Performance Insights attributes round-trip (DbiResourceId, PerformanceInsightsEnabled, KMS key, retention); subnet groups record their subnets and block deletion of a subnet a DB still uses; DB Proxy CRUD with a default target group and cluster/instance targets
Performance Insights ✅ Core X-Amz-Target: PerformanceInsightsv20180227.* GetResourceMetrics, DescribeDimensionKeys, ListAvailableResourceMetrics/Dimensions, GetResourceMetadata — deterministic synthetic load data keyed off RDS DbiResourceId
ElastiCache ✅ Core form-encoded body, Version=2015-02-02 Subnet group, parameter group, cache cluster, and replication group CRUD — endpoints resolve to a real Valkey sidecar; status always available
ACM ✅ Core X-Amz-Target: CertificateManager.* Certificate CRUD — RequestCertificate generates a real self-signed cert; status always ISSUED; PEM downloadable via /_nimbus/acm/certs/{arn}
Route 53 ✅ Core /2013-04-01/ path prefix Hosted zone and record set CRUD — GetChange always returns INSYNC; no DNS resolution
CloudWatch Metrics ✅ Core X-Amz-Target: GraniteServiceVersion20100801.* PutMetricData, ListMetrics (with name-only and name+value dimension filters), GetMetricStatistics, GetMetricData, metric alarms (structural, always OK), tags
Cognito ✅ Core X-Amz-Target: AWSCognitoIdentityProviderService.* User pool and client CRUD, tags — infra lifecycle for terraform apply; auth flows (JWT) in Phase 2
Kinesis ✅ Core X-Amz-Target: Kinesis_20131202.* Stream CRUD, PutRecord/PutRecords, GetShardIterator, GetRecords — in-memory ring buffer per shard; partition key hashed to shard via MD5; Lambda ESM runner (1 s poll, full Kinesis event envelope)
Step Functions ✅ Core X-Amz-Target: AWSStepFunctions.* CreateStateMachine / StartExecution; Pass, Succeed, Fail, Choice, Wait, Task (→Lambda), Parallel, Map; Catch + Retry
Internal Dev APIs ✅ Full /_nimbus/ path prefix State dump, reset, health, live Lambda registration (forge dev tunnel), per-service inspection endpoints

Using the AWS SDK

Point your AWS SDK at http://localhost:4566. Nimbus accepts any credentials.

Python (boto3):

import boto3

s3 = boto3.client(
    "s3",
    endpoint_url="http://localhost:4566",
    aws_access_key_id="test",
    aws_secret_access_key="test",
    region_name="us-east-1",
)
s3.create_bucket(Bucket="my-bucket")

JavaScript (AWS SDK v3):

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

const s3 = new S3Client({
  endpoint: "http://localhost:4566",
  region: "us-east-1",
  credentials: { accessKeyId: "test", secretAccessKey: "test" },
  forcePathStyle: true,
});

Go:

cfg, _ := config.LoadDefaultConfig(context.TODO(),
    config.WithRegion("us-east-1"),
    config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider("test", "test", "")),
    config.WithEndpointResolverWithOptions(
        aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
            return aws.Endpoint{URL: "http://localhost:4566"}, nil
        }),
    ),
)

AWS CLI v2:

Set AWS_ENDPOINT_URL once and omit --endpoint-url from every command:

export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_DEFAULT_REGION=us-east-1

aws s3 mb s3://my-bucket
aws sqs create-queue --queue-name my-queue
aws lambda invoke --function-name my-func --payload '{}' --cli-binary-format raw-in-base64-out response.json

These variables are exported automatically when using the infra/ dev harness (make start).


nimbuslocal CLI

nimbuslocal is a thin wrapper around the aws CLI that automatically injects the Nimbus endpoint. It's a drop-in replacement for awslocal.

nimbuslocal s3 mb s3://my-bucket
nimbuslocal sqs create-queue --queue-name my-queue
nimbuslocal dynamodb list-tables
nimbuslocal secretsmanager create-secret --name /myapp/db-password --secret-string "secret"
nimbuslocal ssm put-parameter --name /myapp/db-host --value localhost --type String
nimbuslocal ses verify-email-identity --email-address sender@example.com
nimbuslocal lambda invoke --function-name my-func --payload '{}' response.json
nimbuslocal apigateway create-rest-api --name my-api

Install:

curl -fsSL https://raw.githubusercontent.com/nimbus-local/nimbus/master/install.sh | sh

The script detects your OS and architecture, downloads the right binary to ~/.local/bin, and adds it to your shell profile automatically.

Or install manually with Go:

go install github.com/nimbus-local/nimbus/cmd/nimbuslocal@latest
# ensure $GOPATH/bin is on your PATH
export PATH="$PATH:$HOME/go/bin"

To uninstall:

# If installed via the script:
rm ~/.local/bin/nimbuslocal
# Then remove the managed block from your shell profile (~/.zshrc etc.):
# ### MANAGED BY NIMBUSLOCAL START (DO NOT EDIT)
# ...
# ### MANAGED BY NIMBUSLOCAL END (DO NOT EDIT)

# If installed via go install:
rm ~/go/bin/nimbuslocal

Configuration

All configuration is via environment variables:

Variable Default Description
NIMBUS_PORT 4566 Edge port — advertised in generated SQS queue URLs and followed by the container HEALTHCHECK, so docker compose up --wait works on non-default ports (EXPOSE 4566 remains documentation of the default)
NIMBUS_EXTERNAL_URL (none) Base URL advertised in generated resource URLs (SQS queue URLs) when it differs from the listen address — reverse proxies, remapped Docker ports
NIMBUS_DATA_DIR /var/lib/nimbus (Docker) Storage root for S3 objects
AWS_DEFAULT_REGION us-east-1 Default region
NIMBUS_DYNAMODB_ENDPOINT http://dynamodb-local:8000 DynamoDB Local sidecar URL
NIMBUS_LOG_LEVEL info debug, info, warn, error
SERVICES (all) Comma-separated list to enable
NIMBUS_ENDPOINT_URL http://localhost:4566 Used by nimbuslocal CLI

Health Check

GET /_nimbus/health
GET /_localstack/health   (alias for LocalStack compatibility)
{"status":"running","services":["dynamodb","lambda","apigateway","ses","secretsmanager","ssm","sqs","s3"]}

Migrating from LocalStack

  1. Replace localstack/localstack with ghcr.io/nimbus-local/nimbus in your docker-compose.yml
  2. Add the dynamodb-local sidecar if you use DynamoDB
  3. Change S3_ENDPOINT_URL (or equivalent) from http://localstack:4566 to http://nimbus:4566
  4. Replace awslocal with nimbuslocal in scripts
  5. That's it. The port, credential handling, and API responses are compatible.

Architecture

Nimbus is a single Go binary. All AWS service traffic enters on port 4566. The edge router inspects each request — via X-Amz-Target header, Action query param, or URL path — and dispatches to the appropriate service handler. S3 is the catch-all and is always registered last.

Each service is a self-contained package implementing a simple Service interface. Adding a new service means implementing the interface and registering it in cmd/nimbus/main.go — nothing else changes.

internal/
  router/               # Edge router — detects and dispatches
  services/
    s3/                 # S3 implementation (filesystem-backed)
    sqs/                # SQS (in-memory)
    dynamodb/           # DynamoDB proxy to DynamoDB Local
    secretsmanager/     # Secrets Manager (in-memory)
    ssm/                # SSM Parameter Store (in-memory)
    ses/                # SES — captures emails, never sends
    lambda/             # Lambda REST API
    apigateway/         # API Gateway management + execute-api
  auth/                 # Credential extraction (accepts anything)
  config/               # Environment-based configuration
  uid/                  # UUID generation
cmd/
  nimbus/               # Server entrypoint
  nimbuslocal/          # AWS CLI wrapper
docs/
  services/             # Per-service API reference

Local development

The infra/ directory contains a full dev harness: Docker Compose, Terraform fixtures, and a smoke test script that exercises every service end-to-end.

Prerequisites: Docker, Terraform, AWS CLI v2.

cd infra
Goal Command
Start Nimbus + DynamoDB Local make start
Provision all test resources make apply
Run smoke tests make smoke-test
Provision + smoke test in one step make test
Rebuild after Go changes make stop && make start && make apply
Tear everything down make clean

make apply is idempotent — safe to re-run. All AWS credentials are set automatically to dummy values so no environment setup is required.


Contributing

PRs welcome. If you're adding a new AWS service, implement the services.Service interface in internal/services/<n>/ and register it in cmd/nimbus/main.go.

Please keep the spirit of the project: no accounts, no tokens, no telemetry, no commercial restrictions. MIT licensed contributions only.

See CONTRIBUTING.md for details.


License

MIT — see LICENSE.

This project is not affiliated with Amazon Web Services or LocalStack.

Directories

Path Synopsis
cmd
nimbus command
nimbuslocal command
internal
jsonhttp
Package jsonhttp provides shared HTTP helpers for AWS JSON-protocol services.
Package jsonhttp provides shared HTTP helpers for AWS JSON-protocol services.
services/acm
Package acm emulates the AWS Certificate Manager (ACM) control plane.
Package acm emulates the AWS Certificate Manager (ACM) control plane.
services/alb
Package alb emulates the AWS ELBv2 (ALB) control plane.
Package alb emulates the AWS ELBv2 (ALB) control plane.
services/apigateway
Package apigateway emulates the AWS API Gateway REST API management plane and the execute-api runtime.
Package apigateway emulates the AWS API Gateway REST API management plane and the execute-api runtime.
services/appsync
Package appsync emulates the AWS AppSync GraphQL API management plane.
Package appsync emulates the AWS AppSync GraphQL API management plane.
services/cloudfront
Package cloudfront emulates the AWS CloudFront distribution control plane.
Package cloudfront emulates the AWS CloudFront distribution control plane.
services/cloudwatchmetrics
Package cloudwatchmetrics emulates the AWS CloudWatch Metrics API.
Package cloudwatchmetrics emulates the AWS CloudWatch Metrics API.
services/ec2
Package ec2 emulates the AWS EC2 API for VPC-related resources.
Package ec2 emulates the AWS EC2 API for VPC-related resources.
services/ecr
Package ecr emulates the AWS Elastic Container Registry management plane and the Docker V2 registry protocol for local development.
Package ecr emulates the AWS Elastic Container Registry management plane and the Docker V2 registry protocol for local development.
services/ecs
Package ecs emulates the AWS Elastic Container Service (ECS) control plane for local development.
Package ecs emulates the AWS Elastic Container Service (ECS) control plane for local development.
services/efs
Package efs emulates the AWS Elastic File System (EFS) API.
Package efs emulates the AWS Elastic File System (EFS) API.
services/elasticache
Package elasticache emulates the AWS ElastiCache control plane.
Package elasticache emulates the AWS ElastiCache control plane.
services/pi
Package pi emulates the AWS Performance Insights API (service prefix PerformanceInsightsv20180227) with synthetic metric data.
Package pi emulates the AWS Performance Insights API (service prefix PerformanceInsightsv20180227) with synthetic metric data.
services/rds
Package rds emulates the AWS RDS/Aurora control plane.
Package rds emulates the AWS RDS/Aurora control plane.
services/route53
Package route53 emulates the AWS Route 53 control plane.
Package route53 emulates the AWS Route 53 control plane.
services/s3control
Package s3control emulates the AWS S3 Control management plane.
Package s3control emulates the AWS S3 Control management plane.
uid

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL