MiniStack: a free local AWS emulator you can install with pip
Ministack: Free, open-source local AWS emulator - 60+ services, Terraform compatible, real databases. Free forever. MIT licensed.
At a glance
- What is it?
- MiniStack emulates 60+ AWS services on port 4566 under the MIT licence, with real Postgres, Redis and Docker containers behind some services. Here is how it installs, how multi-tenancy works, and where it stops being the right tool.
- Who is it for?
- Adopt MiniStack if you are building or testing against AWS APIs locally and want a single port, an MIT licence and no sign-up. Do not adopt it if you need a faithful reproduction of AWS control-plane semantics, or if you depend on a service the README does not list.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap MiniStack fills: local AWS without a paid tier
The README opens with a direct claim: LocalStack moved its core services behind a paid plan, and MiniStack is positioned as the free alternative for people who used LocalStack Community in local development and CI. That framing tells you the intended audience. It is not aimed at teams doing full cloud integration testing against AWS itself. It is aimed at developers who want boto3, the AWS CLI, Terraform, CDK or Pulumi to talk to something on localhost that answers with AWS-shaped responses, without an account or an API key.
The scope is broad on paper: 60+ services on a single port, multi-account and multi-region support, and MIT licensing. The repository is Python, requires Python 3.10 or later, and the current version in pyproject.toml is 1.5.15. The project classifies itself as Development Status 4 - Beta, which is worth taking at face value rather than treating as a formality.
Who it is for, concretely: someone writing a test suite that creates an S3 bucket, puts an object, sends an SQS message, and asserts on the result. Someone running Terraform plan and apply against a throwaway endpoint. Someone who wants a Bedrock-shaped API in front of a local model server. Those are the use cases the README builds its examples around.
How MiniStack emulates AWS on a single port
The architecture is a single HTTP gateway. Everything listens on port 4566, and the service you reach is determined by the request shape rather than by a port number. The README describes HTTP/2 (h2c) support and a startup time under two seconds. That single-port design is what makes the tool drop-in for SDKs: you set one endpoint URL and stop thinking about routing.
State is scoped by two things the README calls out explicitly. The SigV4 region scopes the state, and a 12-digit AWS_ACCESS_KEY_ID becomes the account ID used for ARN generation. Non-numeric keys fall back to MINISTACK_ACCOUNT_ID or to 000000000000. That is the whole multi-tenancy mechanism: no configuration, no tenant registry, just the shape of the credential you present.
Not every service is a mock. The README states that RDS spins up actual Postgres and MySQL containers, ElastiCache spins up real Redis or Valkey, ECS runs real Docker containers, and Athena runs real SQL through DuckDB in the full image. This is the most consequential design decision in the project. Emulating a database protocol is hard; starting a container and proxying to it is not. The trade-off is that those services need a Docker socket mounted into the MiniStack container, which the docker-compose.yml does with a volume mount on /var/run/docker.sock.
There is an internal control plane under /_ministack/ that the AWS APIs do not cover. It exposes health, reset, runtime config, and inspection endpoints for SES messages and SQS queues. That is where the project stops pretending to be AWS and starts being a test harness.
Installing MiniStack and running a first request
The README gives three install paths. The simplest is PyPI, which needs Python 3.10 or later. After installing, running the ministack command starts the gateway on http://localhost:4566, and the README notes GATEWAY_PORT can change it.
pip install ministack
ministackThe Docker path is one command and pulls the image from Docker Hub. For services that need to launch containers, the README adds a second variant that mounts the Docker socket.
docker run -p 4566:4566 ministackorg/ministack
docker run -p 4566:4566 -v /var/run/docker.sock:/var/run/docker.sock ministackorg/ministackOnce it is up, the health endpoint is the fastest way to confirm it is answering. The README also notes compatibility with LocalStack's own health paths, which matters if you are swapping tools behind an existing script.
curl http://localhost:4566/_ministack/health
curl http://localhost:4566/_localstack/healthA first real use, drawn from the README's multi-tenancy example: set a 12-digit access key and call STS. The account in the response should match the key you set, not a default.
export AWS_ACCESS_KEY_ID=111111111111
export AWS_SECRET_ACCESS_KEY=test
aws --endpoint-url=http://localhost:4566 sts get-caller-identityFor CI, the reset endpoint is the piece worth wiring in early. Calling it between tests wipes state without restarting the container, and adding init=1 re-runs the boot.d and ready.d scripts so seed resources come back.
curl -X POST http://localhost:4566/_ministack/reset
curl -X POST "http://localhost:4566/_ministack/reset?init=1"The reset endpoint and why it matters more than the service list
A 60+ service count is a marketing number until you check whether the services you use behave consistently. What MiniStack offers that is harder to find elsewhere is a first-class state reset. The README describes /_ministack/reset as wiping every service back to empty, and the ?init=1 variant as re-running init scripts afterwards. For test suites, that removes the usual workaround of tearing down and recreating a container per test class.
The runtime config endpoint is the second piece of that harness. It changes service-level settings without a restart, and the README documents a specific set of keys: lambda_svc.LAMBDA_EXECUTOR to switch Lambda between local and docker execution, athena.ATHENA_ENGINE to pick duckdb or mock, athena.ATHENA_DATA_DIR for DuckDB data files, and two Step Functions keys, stepfunctions._sfn_mock_config and stepfunctions._SFN_WAIT_SCALE. That last one scales Wait state durations and retry sleeps, with 0 skipping all waits. If you have ever watched a Step Functions test sit idle for thirty seconds, the value of that key is obvious.
The inspection endpoints are narrower but practical. /_ministack/ses/messages returns every message sent through SES grouped by account, with an optional account query parameter. /_ministack/sqs/messages returns queue messages grouped by account, including Body, MessageId, ReceiveCount, VisibleAt, IsVisible, MessageAttributes, and FIFO group and dedup fields. Asserting on a message that never left the machine is a common testing need, and these endpoints exist to serve it.
Where MiniStack is the wrong tool
The README does not document rollback, and it does not claim wire-level fidelity for every service. That omission matters. An emulator that answers correctly for the common path can still diverge on error codes, pagination edge cases, eventual consistency timing, or IAM evaluation. The pyproject.toml notes that IAM enforcement reads request and response shapes from botocore's service models to map a wire request to an IAM action, and that without botocore the lookup finds nothing and AUTH=true would allow what it cannot classify. That is an explicit statement about the limits of IAM enforcement: it classifies what it can see, and the model version is pinned to botocore 1.43.63 to keep pip installs and Docker runs classifying against identical service models.
If your goal is to validate that your application behaves correctly under AWS's real semantics, an emulator is the wrong instrument regardless of how many services it lists. MiniStack is for testing your code's use of the AWS API, not AWS's behaviour.
The Docker socket mount is a second boundary. Running the container with /var/run/docker.sock mounted gives it control over your Docker daemon, which is a meaningful privilege expansion in any shared or CI environment. The README presents the mount as necessary for RDS, ECS and Lambda containers, so the choice is between a smaller emulated surface and a broader privilege grant. There is no third option documented.
The image variants also matter. The README states the full image is roughly 360 MB versus about 110 MB, and that Athena and native PostgreSQL and MySQL drivers only work in the full image. If you install the default image and expect Athena to run real SQL, you will be disappointed for a packaging reason, not a capability one.
MiniStack versus LocalStack and moto: different bets
MiniStack's README frames the comparison itself: LocalStack moved core services behind a paid plan, and MiniStack is the free alternative. The practical difference is licensing and cost model rather than architecture. LocalStack's community edition restricts which services you get; MiniStack is MIT licensed and the README says free forever. If your constraint is a budget line for local development tooling, that is the deciding factor.
The comparison with moto is a different axis. Moto is a Python library that mocks AWS APIs in-process, which means your tests import it and no server runs. MiniStack is a running gateway you point an endpoint URL at. That distinction determines your test topology: moto fits unit tests that want no external process, while MiniStack fits integration tests and Terraform runs that need a real HTTP endpoint and, for some services, real backing containers. Neither approach is strictly better; they solve for different test shapes, and the README's own examples are all endpoint-URL based.
The real-infrastructure choice is where MiniStack makes its clearest bet. Starting actual Postgres, Redis and Docker containers gives more realistic behaviour than mocking a protocol, at the cost of Docker as a hard dependency for those services. A pure in-process mock has no such dependency and no such fidelity. If you are choosing between them, decide first whether your tests need a live database connection or only a stubbed response.
Maintenance, licensing and what to check before adopting
The repository is not archived, and the last push was on 2026-09-22. Releases have been frequent: v1.5.13 on 2026-09-17, v1.5.14 on 2026-09-20, and v1.5.15 on 2026-09-21. That cadence is a real maintenance signal, and it also means the emulated surface is a moving target. Pin the version you test against, because a patch release can change how a service responds.
The licence is MIT, declared in the LICENSE file and in pyproject.toml. That permits commercial use, modification and redistribution, and it comes with no warranty. This is not legal advice; if your organisation has licence review, the MIT terms are the ones to review.
Upgrade cost is mostly the botocore pin. Both pyproject.toml and requirements.txt pin botocore to 1.43.63, and the comment explains why: awscli 1.45.63 requires that exact version, and keeping pip installs and Docker runs on the same service models means IAM classification behaves identically in both. If you already pin botocore for your own tooling, check for a conflict before installing MiniStack alongside it.
The repository carries a CHANGELOG.md, CONTRIBUTING.md and SECURITY.md, and there is a Testcontainers directory alongside the tests directory. Those are the files to read first if you are evaluating whether the project's release process matches your expectations.
Editorial conclusion
Adopt MiniStack if you are building or testing against AWS APIs locally and want a single port, an MIT licence and no sign-up. Do not adopt it if you need a faithful reproduction of AWS control-plane semantics, or if you depend on a service the README does not list. Before committing, run the health endpoint, check that your specific service appears, and read the CHANGELOG to see how the emulated surface is changing between v1.5.x releases.
Frequently asked questions
What are the key differences between LocalStack and MiniStack?
The README states that LocalStack moved its core services behind a paid plan and presents MiniStack as the free alternative. MiniStack is MIT licensed, emulates 60+ services on port 4566, and the README also cites a smaller image and lower idle memory than LocalStack. It additionally exposes LocalStack-compatible health endpoints at /_localstack/health and /health.
What is a free alternative to LocalStack?
MiniStack describes itself as exactly that: a free, open-source local AWS emulator under the MIT licence, with no account, API key or sign-up required. It installs from PyPI with pip install ministack or from Docker Hub as ministackorg/ministack.
How do I install MiniStack?
The README gives three paths: pip install ministack followed by running ministack, docker run -p 4566:4566 ministackorg/ministack, or cloning the repository and running docker compose up -d. A full image variant, ministackorg/ministack:full, adds DuckDB for Athena and native PostgreSQL and MySQL drivers.
What is MiniStack?
MiniStack is a free, open-source local AWS emulator written in Python that serves 60+ AWS services on a single port, 4566. The README describes it as drop-in compatible with boto3, the AWS CLI, Terraform, CDK, Pulumi and other SDKs, with multi-account and multi-region support.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ministackorg-ministack)