How to Use LocalStack: The Beginner's Guide (First Install, the awslocal Lesson, First S3 Bucket, and the Endpoint-URL Trap)
CodexFuse Team · 2026-11-07T07:09:07.053Z · 18 min read min read
How Do I Use LocalStack?
Learning how to use localstack takes seven moves: get a free auth token, install the lstk launcher, start the emulator, point your tools at the local endpoint, create your first S3 bucket with awslocal, save state with persistence, and know where the free Hobby plan ends. This localstack tutorial follows the official LocalStack documentation and the project release pages, with every fact checked as of November 2026 and pinned to the current Docker image, 2026.10.6. LocalStack emulates AWS APIs locally, not a real cloud, so your code talks to a container on your own machine instead of to Amazon, and nothing you create here ever leaves your laptop.
CodexFuse offers no LocalStack tool, so this guide teaches the real program on your own machine, not a web version of it. No Facebook promotion applies to this guide. The container route is covered in our Docker beginner guide, which you should read first if Docker is new to you.
- Create a free LocalStack account and copy your auth token.
- Install lstk and run lstk doctor to check your machine.
- Start the emulator with lstk start and confirm it is healthy.
- Point the AWS CLI at the local endpoint with awslocal or lstk aws.
- Create your first S3 bucket and upload one file.
- Turn on persistence so your buckets survive a restart.
- Check the Hobby limits before you use LocalStack for paid work.
What Is LocalStack, Exactly?
A localstack aws setup is a local copy of the AWS APIs that runs in a Docker container on your own machine. It answers the same API calls your code already makes to S3, Lambda, DynamoDB, SQS, and more, and it stores the results locally, so you can build and test without an AWS account or a cloud bill. The LocalStack documentation lists 113 AWS service documentation entries as of August 2026, according to an independent guide that surveyed the docs, and S3, Lambda, and DynamoDB are the usual starting points.
| Fact | Value |
|---|---|
| Repository | localstack/localstack on GitHub |
| Stars | 65,125 |
| Forks | 4,834 |
| Open issues | 0, issues closed on archival |
| Created | 25 October 2016, 3,665 days ago, 10.03 years ago |
| Last GitHub release | v4.14.0, published 26 February 2026, 254 days ago |
| Current Docker image | 2026.10.6, updated 4 November 2026, 3 days ago |
| Repository status | Archived 23 March 2026, 229 days ago |
| License | Not asserted by the GitHub API |
| Default branch | main |
| Docker Hub pulls | 618,720,492 |
The repository, localstack/localstack on GitHub, was created on 25 October 2016, which makes it 3,665 days old, or 10.03 years, and it holds 65,125 stars against 4,834 forks as of 7 November 2026. That works out to 13.47 stars per fork, and the Docker Hub image has 618,720,492 pulls, which is 9,501 pulls per star, although the Docker Hub pull count is cumulative all-time and not a count of current-version downloads. The last GitHub release, v4.14.0, is 254 days old, and v4.14.0 is the last GitHub release, not the current version, because releases stopped when the repository was archived on 23 March 2026, 229 days ago.
The open issues count reads zero only because the repository is archived, so do not read it as a bug-free project. March 2026 changed LocalStack more than any release before it, because release 2026.03.0, published 23 March 2026, merged the old Community and Pro images into one unified image, switched versioning from semver to CalVer, and made a free auth token mandatory, and the span from 2026.03.0 to the current 2026.10.6 image is 226 days. The last three GitHub releases, v4.13.0, v4.13.1, and v4.14.0, spanned 28 days, with gaps of 4 days and 24 days, while the v4.12.0 to v4.14.0 span was 77 days, so the old release line was moving fast right up to the archive date.
How Do I Install LocalStack?
A localstack install starts with the lstk launcher, which handles the auth token and the container lifecycle in one workflow. A localstack docker install starts with one Docker command instead, and both routes need a working Docker installation first. The machine that runs the stack needs a stable home, and the guide to that machine is our what is VPS hosting page, which explains the server choice before you install anything on it.
| Route | Command | Note |
|---|---|---|
| lstk, recommended | brew install localstack/tap/lstk, then lstk start | Handles auth in a browser login flow |
| Docker run | docker run with LOCALSTACK_AUTH_TOKEN | One command, pin the 2026.10.6 tag |
| Docker Compose | Official compose file with the gateway ports | Best for a version-controlled setup |
| Helm | helm repo add plus helm upgrade install | Needs a Kubernetes cluster |
| pip install localstack | No longer in the official docs | Old CLI, deprecated, do not use |
brew install localstack/tap/lstk lstk doctor lstk start
docker run --rm -it \
-p 127.0.0.1:4566:4566 \
-p 127.0.0.1:4510-4559:4510-4559 \
-e LOCALSTACK_AUTH_TOKEN=your-token-here \
-v /var/run/docker.sock:/var/run/docker.sock \
localstack/localstack:2026.10.6
services:
localstack:
image: localstack/localstack:2026.10.6
ports:
- "127.0.0.1:4566:4566"
environment:
- LOCALSTACK_AUTH_TOKEN=your-token-here
- PERSISTENCE=1
volumes:
- ./volume:/var/lib/localstack
- /var/run/docker.sock:/var/run/docker.sock
The old route, pip install localstack followed by localstack start, is gone from the official installation page, and the localstack start command is deprecated, superseded by lstk. The localstack-cli repository says so in its own description, with 28 stars, and PyPI still publishes localstack 2026.8.2, but the docs no longer teach it. Do not follow any guide that starts with the old CLI, because its steps predate the March 2026 change.
Get the token first, because no current image starts without one: create a free account at app.localstack.cloud, copy the token, and either let lstk store it from the browser login flow or export it as LOCALSTACK_AUTH_TOKEN. Run lstk doctor before you start, because it checks DNS, HTTPS access, the container engine, memory, and disk, and each failed check prints a concrete fix. Check the install with lstk status, which prints the running version and the endpoint, or with curl against the health endpoint, and the same health-check idea is what our Prometheus beginner guide watches on any service.
The Helm route is the one for clusters: add the localstack-repo chart source, then install the chart, and the guide to the cluster it lands on is our Kubernetes beginner guide. The Desktop app and the Docker Desktop extension are the GUI routes, for readers who prefer a window over a terminal.
What Is the awslocal Lesson?
awslocal is a thin wrapper around the AWS CLI that points every command at your local emulator and fills in placeholder credentials for you. It comes from the awscli-local package, version 0.23.0, whose repository holds 1,305 stars and was last pushed on 9 October 2026. The newer wrapper is lstk aws, which is what the current official docs use, and this section teaches both, because awslocal is the name every older guide uses.
pip install awscli-local awslocal s3 ls awslocal s3 mb s3://my-first-bucket
The lesson is that awslocal is a convenience, not a requirement, and every one of its commands has a plain aws equivalent with an endpoint flag. If you use the plain AWS CLI, add the endpoint flag to every call, or set the endpoint once in your environment, or save it in a named profile. The endpoint hostname the docs now recommend is http://localhost.localstack.cloud:4566, which resolves to your own machine from the host and to the container from inside Docker networks, while plain http://localhost:4566 still works from the host.
| Method | How | When to use it |
|---|---|---|
| Per-command flag | aws with the endpoint-url flag | One-off commands |
| Environment variable | AWS_ENDPOINT_URL plus test credentials | A whole terminal session |
| Wrapper | awslocal or lstk aws | Daily use, no flags to remember |
| Named profile | localstack profile in the AWS config files | A permanent local setup |
How Do I Create My First S3 Bucket?
A localstack s3 bucket is the first resource most beginners create, because S3 is the simplest service to verify and the one every later example builds on. Create it with one command, list your buckets to confirm it exists, and upload one file to prove the round trip works. The commands below use lstk aws, the wrapper the current docs teach, and the awslocal equivalents are identical apart from the command name.
lstk aws s3api create-bucket --bucket sample-bucket lstk aws s3api list-buckets lstk aws s3api put-object --bucket sample-bucket --key hello.txt --body hello.txt lstk aws s3 presign s3://sample-bucket/hello.txt
S3 accepts any credentials by default, because signature validation is off, and the working pair is test for the access key and test for the secret key, with us-east-1 as the region. Virtual-hosted-style addressing is the default and recommended approach, so the endpoint carries an s3 prefix, while path style is the fallback for connections from another container where wildcard subdomains do not resolve. LocalStack does not validate the signature or the expiration of pre-signed URLs by default, so treat a local pre-signed URL as a convenience for testing, not as a security control.
What Is the Endpoint-URL Trap?
The endpoint-URL trap is the single most common beginner failure: you run a plain aws command, it goes to real AWS instead of your local emulator, and it either fails on missing credentials or, worse, acts on a real account. LocalStack's AWS CLI guide, as summarized by an independent guide, says a missing endpoint URL is the most common setup error, and the fix is to point every call at the gateway, port 4566. The trap is easy to fall into because the commands look identical with and without the flag, and the only visible difference is where the request lands.
The three defenses are a flag on every command, an environment variable for the session, or a wrapper that sets both for you, and the section above lists all three. Terraform needs the same treatment, because its AWS provider also defaults to real AWS, and the guide to the tool is our Terraform beginner guide. Inside a Lambda function, LocalStack offers transparent endpoint injection, which resolves AWS hostnames to the container so your code needs no changes, and you can opt out of it with one setting if you want explicit endpoints instead.
How Do I Keep State Between Restarts?
LocalStack is ephemeral by default, so stopping the instance clears the state, and your buckets and tables disappear with it. Turn on persistence with PERSISTENCE set to 1 and a volume mounted at /var/lib/localstack, and the official Compose example mounts a local volume directory for exactly this purpose. With lstk, pass the same setting as LOCALSTACK_PERSISTENCE set to 1, and the default volume directory on Linux is ~/.cache/localstack/volume.
Hobby does not include local state persistence, according to the official licensing table, which marks it unavailable on Hobby and available on Base, Ultimate, Enterprise, and Student. That makes persistence a paid feature in practice, and one secondary guide says the same thing, so the two sources agree. Cloud-based state persistence via Cloud Pods is also paid, with 300 MB of lifetime storage per workspace on Base, 3 GB on Ultimate, and 5 GB per user on Enterprise.
What Does LocalStack Cost?
Hobby is the free plan, for non-commercial use, and it offers a similar level of AWS service emulation to the old Community edition, according to the pricing FAQ. Base is the first paid plan, at $39 per user per month billed annually or $45 per user per month on a monthly commitment, and Ultimate is $89 per user per month, while Enterprise is custom pricing through sales. A 30-day free trial of the paid plans needs no credit card, and CI credits are unlimited on all plans under a fair-use policy since March 2026.
| Plan | Price | Who it is for |
|---|---|---|
| Hobby | Free, non-commercial use | Learning and hobby projects |
| Base | $39 per user per month, annual billing, or $45 monthly | Commercial development, more services |
| Ultimate | $89 per user per month | Teams that need priority support and more storage |
| Enterprise | Custom pricing | Large organizations and governance needs |
| Student | Free with GitHub Education | Verified students |
| Trial | 30 days, no credit card | Trying a paid plan |
Paying annually for Base saves $6 per month, which is $72 per year, or $468 against $540 on monthly billing, a saving of 13.33 percent. Ultimate costs $50 per month more than Base, which is 2.28 times the Base price, and the extra money buys more services, 3 GB of Cloud Pod storage against 300 MB, and priority support. Maintainers of non-commercial open-source projects can apply for a free Ultimate-tier license, and legacy Starter and Teams plans are unavailable for new purchases since 8 May 2026.
LocalStack vs Moto: Which Local AWS Tool Should I Pick?
LocalStack vs moto is the comparison most readers ask about, and the answer is that the two tools solve different problems. Moto is a Python library that mocks AWS services inside your test process, while LocalStack is a running emulator in a Docker container that exposes real HTTP endpoints any language or tool can call. Pick moto for fast unit tests in Python, and pick LocalStack for integration tests, any stack, and anything that needs a real endpoint, including Terraform and the AWS CLI.
| Fact | LocalStack | moto |
|---|---|---|
| What it is | Running AWS emulator in Docker | Python mock library for tests |
| Language | Any language, SDK, CLI, or Terraform | Python only |
| Endpoint | Real HTTP endpoint on port 4566 | None, calls are intercepted in Python |
| Stars | 65,125 | 8,737 |
| Forks | 4,834 | 2,298 |
| Open issues | 0, archived repository | 120 |
| Created | 25 October 2016 | 18 February 2013 |
| Age | 3,665 days, 10.03 years | 5,010 days, 13.72 years |
Moto holds 8,737 stars against 2,298 forks, which works out to 3.80 stars per fork, and its 120 open issues work out to 1.37 per 100 stars. LocalStack holds 56,388 more stars than moto, which is 7.45 times as many, or 645.4 percent more, and 2,536 more forks, although the LocalStack numbers are frozen history from an archived repository. LocalStack is 1,345 days younger than moto, which was created on 18 February 2013, and LocalStack itself vendors a fork of moto with patches, so the two projects are closer than the comparison suggests.
What Are the Seven Mistakes Beginners Make with LocalStack?
Every mistake below comes from a guide written before March 2026, or from a habit that made sense in the old product and breaks in the new one. Read the table once, then check your own setup against it before you open your first issue or blame the emulator. The pattern to remember is that the current product wants a token, the lstk launcher, and an explicit endpoint on every call.
| Mistake | What happens | Fix |
|---|---|---|
| Following a pre-March-2026 guide | Steps for v0.10.7 or v3.8 fail on the current image | Use the official docs and this guide, both current |
| Skipping the auth token | The container refuses to start | Create a free account and set LOCALSTACK_AUTH_TOKEN |
| Using localstack start | The old CLI is deprecated | Use lstk start |
| Setting LAMBDA_EXECUTOR | The setting no longer exists | Mount the Docker socket instead |
| Forgetting the endpoint flag | Commands go to real AWS | Use awslocal, lstk aws, or the endpoint flag |
| Trusting the Docker Docs claim | The guide says the image does not require any API key, which is wrong for current images | Get a token before you start |
| Assuming Hobby keeps state | Buckets vanish on restart | Turn on persistence on a paid plan, or export your state |
Two of these mistakes deserve emphasis: LAMBDA_EXECUTOR was removed in the new provider, so any guide that sets it is teaching a knob that no longer exists, and the Docker Docs guide is the freshest page with the wrong claim, updated 30 days ago. No measured speed benchmark exists for LocalStack against real AWS in this guide, because none was found in the sources fetched for it, so do not quote one from here.
Sources
The facts in this guide come from the official LocalStack documentation, including the installation page, the local-development quickstart, the S3 service page, the configuration reference, and the licensing page, all fetched on 7 November 2026. The repository numbers come from the GitHub API for localstack/localstack and getmoto/moto, fetched the same day, and the Docker Hub numbers come from the Docker Hub API for localstack/localstack, also fetched the same day. The pricing figures come from LocalStack's own site text and the licensing page, because the pricing page renders its prices as images, and the plan table was read from the licensing page directly.
The freshness audit covered the baptiste multi-part arc, whose content is from early 2020 and version 0.10.7, the ubos.tech five-step quickstart, the dev.to complete guide, which is 237 days old, the dev.to nine-part series, whose Part 0 is 182 days old, and the Docker Docs guide, which is 30 days old. The dev.to Part 0 guide is the freshest correct independent walkthrough found, and it covers the March 2026 packaging change, while the Docker Docs guide is the newest page and still carries the wrong no-API-key claim. The AnyGen guide was used as a secondary source for the AWS service count and the endpoint-error summary, and the Floci launch coverage was read for the alternatives context.
The license of the current distribution is contested between secondary sources, with one saying the license moved from Apache to BSL and another saying the code was not relicensed, so this guide asserts neither and reports only what the GitHub API returns, which is no asserted license. The persistence question was resolved from the official licensing table, which marks local state persistence unavailable on Hobby, and the Cloud Pod storage figures come from the same table. No commands in this guide were executed in a live testbed, so every command is documented syntax from the official docs, not a transcript of a run.
from datetime import date
today = date(2026, 11, 7)
ls_created = date(2016, 10, 25)
moto_created = date(2013, 2, 18)
v4140 = date(2026, 2, 26)
v4131 = date(2026, 2, 2)
v4130 = date(2026, 1, 29)
v4120 = date(2025, 12, 11)
archived = date(2026, 3, 23)
img106 = date(2026, 11, 4)
calver_start = date(2026, 3, 23)
docker_docs = date(2026, 10, 8)
devto_part0 = date(2026, 5, 9)
devto_complete = date(2026, 3, 15)
ls_stars = 65125
ls_forks = 4834
moto_stars = 8737
moto_forks = 2298
moto_issues = 120
pulls = 618720492
print("LocalStack repo age days:", (today - ls_created).days)
print("LocalStack repo age years:", round((today - ls_created).days / 365.25, 2))
print("moto repo age days:", (today - moto_created).days)
print("moto repo age years:", round((today - moto_created).days / 365.25, 2))
print("LocalStack younger than moto by days:", (ls_created - moto_created).days)
print("star gap:", ls_stars - moto_stars)
print("star ratio:", round(ls_stars / moto_stars, 2))
print("star percent more:", round((ls_stars - moto_stars) / moto_stars * 100, 1))
print("fork gap:", ls_forks - moto_forks)
print("LocalStack stars per fork:", round(ls_stars / ls_forks, 2))
print("moto stars per fork:", round(moto_stars / moto_forks, 2))
print("moto issues per 100 stars:", round(moto_issues / moto_stars * 100, 2))
print("v4.14.0 age days:", (today - v4140).days)
print("archived age days:", (today - archived).days)
print("2026.10.6 age days:", (today - img106).days)
print("CalVer span 2026.03.0 to 2026.10.6 days:", (img106 - calver_start).days)
print("v4.13.0 to v4.14.0 span days:", (v4140 - v4130).days)
print("v4.13.0 to v4.13.1 gap days:", (v4131 - v4130).days)
print("v4.13.1 to v4.14.0 gap days:", (v4140 - v4131).days)
print("v4.12.0 to v4.14.0 span days:", (v4140 - v4120).days)
print("pulls per star:", round(pulls / ls_stars))
print("Base annual monthly saving dollars:", 45 - 39)
print("Base annual saving per year dollars:", (45 - 39) * 12)
print("Base annual total dollars:", 39 * 12)
print("Base monthly total dollars:", 45 * 12)
print("Base saving percent:", round((45 - 39) / 45 * 100, 2))
print("Ultimate minus Base dollars:", 89 - 39)
print("Ultimate over Base ratio:", round(89 / 39, 2))
print("Docker Docs guide age days:", (today - docker_docs).days)
print("dev.to Part 0 age days:", (today - devto_part0).days)
print("dev.to Complete Guide age days:", (today - devto_complete).days)
Frequently Asked Questions
Is LocalStack free?
LocalStack is free for non-commercial use through the Hobby plan, which needs only a free account and an auth token. Commercial use needs a paid plan, starting with Base at $39 per user per month on annual billing. A 30-day free trial covers the paid plans with no credit card required.
Do I still need an AWS account to use LocalStack?
No AWS account is needed, because LocalStack runs entirely on your own machine and answers API calls locally. You do need a free LocalStack account for the auth token, since no current image starts without one. Your code and data never leave your laptop unless you point them at real AWS yourself.
What happened to localstack start?
The old start command was retired in favor of the lstk launcher, and the localstack-cli repository says so in its own description. The current route is brew install localstack/tap/lstk followed by lstk start, or the Docker run command with an auth token. Guides that start with the old CLI predate the March 2026 change and will not work as written.
Why do my AWS commands hit real AWS instead of LocalStack?
Your commands hit real AWS because no endpoint was set, and the AWS CLI defaults to real AWS when it has no endpoint override. Point every call at the local gateway with the endpoint flag, an environment variable, a named profile, or a wrapper such as awslocal or lstk aws. The endpoint hostname the docs recommend is http://localhost.localstack.cloud:4566, on port 4566.
Is LocalStack better than moto?
LocalStack is better when you need a real local endpoint that any language, SDK, CLI, or Terraform can call, because moto only mocks AWS inside Python tests. Moto is better for fast Python unit tests, because it needs no Docker container and no endpoint at all. Many teams use both, with moto for unit tests and LocalStack for integration tests.




