The core library and runtime of LocalEmu
Project description
LocalEmu
A free, open-source AWS cloud emulator.
Run AWS services locally. No account. No token. No sign-up.
What is LocalEmu?
LocalEmu emulates 132 AWS services on your machine. Use the same AWS CLI, boto3, Terraform, or CDK you already know - just point to localhost:4566.
Build and test against AWS APIs from your laptop with no account, no credentials, no internet. The iteration loop is seconds instead of minutes; you can break, reset, and rebuild as often as you want at zero cost.
Where it counts, the behavior is real, not stubbed: Lambda runs your code in the official AWS runtime images, EC2 instances are real containers on a real VPC with security groups enforced by actual packet filtering, RDS is a real PostgreSQL or MySQL you can open a connection to, and (with IAM_ENFORCEMENT=1) your identity and resource policies actually deny.
Install
pip install localemu[runtime]
That's it. No Java. No tokens. No accounts. Docker is required for services that emulate by running a real engine in a sidecar (Lambda, ECS, EKS via k3d, RDS, OpenSearch, EC2). Everything else is pure Python and needs no Docker.
Start
# Foreground (see the banner and logs)
localemu start
# Detached mode (runs in background)
localemu start -d
# Custom port
localemu start --port 4567
# Stop
localemu stop
Use
LocalEmu ships awsemu - a drop-in replacement for the AWS CLI that automatically points to LocalEmu. No configuration needed:
# S3
awsemu s3 mb s3://my-bucket
awsemu s3 cp file.txt s3://my-bucket/
# DynamoDB
awsemu dynamodb create-table --table-name Users \
--key-schema AttributeName=id,KeyType=HASH \
--attribute-definitions AttributeName=id,AttributeType=S \
--billing-mode PAY_PER_REQUEST
# SQS
awsemu sqs create-queue --queue-name my-queue
# Lambda
awsemu lambda create-function --function-name hello \
--runtime python3.12 --handler handler.handler \
--role arn:aws:iam::000000000000:role/role \
--zip-file fileb://function.zip
# Any of the 132 supported services...
awsemu ecs create-cluster --cluster-name my-cluster
awsemu rds describe-db-instances
awsemu cognito-idp create-user-pool --pool-name my-pool
awsemu sets credentials, region, and endpoint automatically. You can also use the standard AWS CLI, boto3, Terraform, CDK, or Pulumi - just point to http://localhost:4566.
Documentation & examples
The full documentation lives at localemu.cloud/docs: prerequisites, install guide, per-service API reference, and end-to-end use case walkthroughs.
For runnable code, clone the companion examples repository:
git clone https://github.com/localemu/localemu-examples
It ships self-contained tutorials covering common patterns: public + private VPC with EC2 / nginx / NACL, image pipelines, scheduled jobs, IAM least-privilege drills, Step Functions sagas, EKS + kubectl, chaos resilience tests, and more.
Explore
# List all supported services
localemu services
# Show operations for a specific service
localemu services s3
localemu services lambda
localemu services dynamodb
# Check running services
localemu status
# Stop
localemu stop
Dashboard
LocalEmu includes a built-in web dashboard for monitoring and exploring your local AWS environment in real time.
http://localhost:4566/_localemu/dashboard
The dashboard shows:
- Service overview with resource counts and status indicators for all active services
- Resource drill-down: click any service to see tables, buckets, queues, functions, instances, and more
- S3 object browser and DynamoDB item viewer with click-through navigation
- CloudTrail event history with expandable request/response details
- Live activity feed showing API calls as they happen, filterable by service
The dashboard starts automatically with LocalEmu. No configuration needed.
Simulation Features
Test real AWS behavior locally with opt-in feature flags:
# IAM policy enforcement (full AWS evaluation algorithm, see section below)
IAM_ENFORCEMENT=1 localemu start
# API throttling simulation (per-service AWS error codes)
SIMULATE_THROTTLING=1 THROTTLE_RATE=0.05 localemu start
# Network latency injection (realistic per-service delays)
SIMULATE_LATENCY=1 localemu start
# Lambda cold start simulation
LAMBDA_COLD_START_DELAY=3 localemu start
# EC2, ECS, and EKS use real containers automatically when Docker is
# available; no env var needed. Opt out via EC2_VM_MANAGER=none,
# ECS_DOCKER_BACKEND=0, or EKS_K8S_PROVIDER=off.
# Real RDS engines (PostgreSQL / MySQL / MariaDB in containers)
RDS_DOCKER_BACKEND=1 localemu start
Simulation features (IAM enforcement, throttling, latency, cold-start) are disabled by default; zero overhead when off. The container-backed services turn themselves off automatically when the Docker daemon is unavailable.
IAM Policy Enforcement
Run your AWS workload against the same policy rules AWS applies in production. Useful for catching permission errors locally before they surface in a deployed environment.
# Strict mode: deny unauthorized requests with 403 AccessDenied
IAM_ENFORCEMENT=1 localemu start
# Audit mode: log would-be denials, allow the request through
IAM_ENFORCEMENT=soft localemu start
# Bypass enforcement for specific access keys (comma-separated allow-list)
ROOT_ACCESS_KEYS=AKIAIOSFODNN7EXAMPLE IAM_ENFORCEMENT=1 localemu start
What gets evaluated (full AWS algorithm, see policy evaluation logic):
- Explicit
Denyin any policy → deny (identity / resource / permission boundary / session). - Same-account: either identity-policy
AllowOR resource-policyAllowis sufficient. - Permission boundary: must also
Allow(intersection). - Session policies (inline or managed) passed via
AssumeRole: must alsoAllow(intersection).
Policy elements
| Element | Supported |
|---|---|
Action / NotAction with wildcards * ? |
✅ |
Resource / NotResource ARN matching |
✅ |
Principal / NotPrincipal (AWS / Service / Federated / CanonicalUser) |
✅ |
IAM policy variables: ${aws:username}, ${aws:userid}, ${aws:PrincipalTag/*} |
✅ |
| String / Numeric / Date / IpAddress / Bool / Arn / Null operators | ✅ |
IfExists suffix |
✅ |
ForAllValues: / ForAnyValue: set operators |
✅ |
Condition context keys populated per request
aws:PrincipalArn, aws:PrincipalAccount, aws:PrincipalType, aws:SourceIp, aws:CurrentTime, aws:EpochTime, aws:SecureTransport (from TLS scheme), aws:UserAgent, aws:RequestedRegion, aws:username, aws:userid, aws:PrincipalTag/*, aws:RequestTag/*, aws:TagKeys, and aws:MultiFactorAuthPresent (set to "true" only when the caller's session was minted by AssumeRole / GetSessionToken with --serial-number, otherwise absent per AWS spec).
Temporary-credential validation: temporary access keys (ASIA* / LSIA*) must include an X-Amz-Security-Token. Expired sessions return ExpiredTokenException.
Limitations
- Cross-account calls (caller account ≠ resource owner account) are currently treated as same-account. LocalEmu defaults to a single account so this rarely matters; if you emulate multi-account IAM flows, enforcement will be more permissive than AWS.
- Service-principal grants on resource policies (e.g.
Principal: {Service: lambda.amazonaws.com}) are not auto-matched for internal service-to-service calls; useAWSprincipals or*for now.
132 Supported Services
Run localemu services to see the full list. Key services include: ACM, API Gateway, AppSync, Athena, Backup, Batch, Bedrock, CloudFormation, CloudFront, CloudTrail, CloudWatch, CodeBuild, CodeCommit, CodeDeploy, CodePipeline, Cognito, Config, DynamoDB, EC2, ECR, ECS, EFS, EKS, ElastiCache, ELB, ELBv2, Elasticsearch, EMR, EventBridge, Firehose, FSx, Glacier, Glue, GuardDuty, IAM, IoT, Kafka, Kinesis, KMS, Lambda, CloudWatch Logs, Neptune, OpenSearch, Organizations, Pipes, RDS, Redshift, Rekognition, Resource Groups, Route53, S3, SageMaker, Scheduler, Secrets Manager, SES, SESv2, SNS, SQS, SSM, Step Functions, STS, Textract, Transcribe, Transfer, WAFv2, X-Ray, and more.
Python (boto3)
import boto3
s3 = boto3.client("s3",
endpoint_url="http://localhost:4566",
aws_access_key_id="AKIAIOSFODNN7EXAMPLE",
aws_secret_access_key="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
region_name="us-east-1",
)
s3.create_bucket(Bucket="my-bucket")
s3.put_object(Bucket="my-bucket", Key="hello.txt", Body=b"Hello!")
Terraform
provider "aws" {
access_key = "AKIAIOSFODNN7EXAMPLE"
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
region = "us-east-1"
skip_credentials_validation = true
skip_metadata_api_check = true
endpoints {
s3 = "http://localhost:4566"
dynamodb = "http://localhost:4566"
lambda = "http://localhost:4566"
sqs = "http://localhost:4566"
# all services on the same endpoint
}
}
Persistence
By default, LocalEmu state is ephemeral. To keep your resources across restarts:
# Local
PERSISTENCE=1 localemu start
# Docker
docker run -d --name localemu \
-p 4566:4566 \
-v localemu-data:/var/lib/localemu \
-e PERSISTENCE=1 \
--user root \
localemu/localemu
State is saved on shutdown and restored on startup. S3 buckets, DynamoDB tables, Lambda functions, SQS queues, Secrets Manager secrets. Everything survives.
Save strategies (set via SNAPSHOT_SAVE_STRATEGY):
ON_SHUTDOWN(default): saves when LocalEmu stopsSCHEDULED: saves every 15 seconds (configurable viaSNAPSHOT_FLUSH_INTERVAL)MANUAL: save/load viaPOST /_localemu/state/saveandPOST /_localemu/state/load
Check status: GET /_localemu/state/status
Docker (alternative)
# Linux
docker run --rm -d -p 4566:4566 -p 4510-4559:4510-4559 \
-v /var/run/docker.sock:/var/run/docker.sock \
--group-add docker \
localemu/localemu
# macOS (Docker Desktop)
docker run --rm -d -p 4566:4566 -p 4510-4559:4510-4559 \
-v /var/run/docker.sock:/var/run/docker.sock \
--user root \
localemu/localemu
Why
--user rooton macOS? Lambda, ECS, and EC2 services spawn real Docker containers for function execution. On Docker Desktop for Mac the socket is owned byrootinside the container regardless of host GID, so the non-rootlocalemuuser cannot access it. On Linux, adding thedockergroup (--group-add docker) is sufficient.
Using the AWS CLI with Docker
When LocalEmu runs in Docker, use the standard AWS CLI from your host:
# Option A: set the endpoint once via env var (recommended)
export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=us-east-1
aws s3 ls
aws dynamodb list-tables
aws lambda list-functions
# Option B: create a host-side awsemu alias
alias awsemu='aws --endpoint-url=http://localhost:4566 --region us-east-1'
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
awsemu s3 ls
awsemu sqs list-queues
# Option C: use awsemu inside the container
docker exec localemu bash -c \
'. /opt/code/localemu/.venv/bin/activate && awsemu s3 ls'
Tip: Option A with
AWS_ENDPOINT_URLis the cleanest: boto3 and the AWS CLI both read it automatically. Your code works identically on LocalEmu and real AWS by just unsetting the env var.
Contributing
License
Copyright (c) 2026 TocConsulting and LocalEmu contributors. Copyright (c) 2017-2026 LocalStack contributors. Copyright (c) 2016 Atlassian and others.
Apache License, Version 2.0. See LICENSE and NOTICE.
LocalEmu is a fork of LocalStack, which was archived by its maintainers. We are grateful to all original contributors.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file localemu-1.0.0.tar.gz.
File metadata
- Download URL: localemu-1.0.0.tar.gz
- Upload date:
- Size: 11.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5bf3839afdcadc453d7df000d59847a4a73a0cce291c3db71a6479bb00881933
|
|
| MD5 |
e3329b5cf797308e1dbd2adcb87364bb
|
|
| BLAKE2b-256 |
04775423c32768831e097f6858023e6e33fc998b8f399c693eb1b6e0b745ecee
|
File details
Details for the file localemu-1.0.0-py3-none-any.whl.
File metadata
- Download URL: localemu-1.0.0-py3-none-any.whl
- Upload date:
- Size: 12.5 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d500df1c302d38357d0e861cc92ac8d896673bdf405805785bb3f6a3c69e204b
|
|
| MD5 |
ce44c0a31c8edf6fd2fb4c7c8c8d38a2
|
|
| BLAKE2b-256 |
24830a3a283305dc139424e1b169ffa2b55a7dba66d3a4867859b1b07a245ec2
|