lstk CLI
Introduction
Section titled “Introduction”lstk is a high-performance command-line interface for LocalStack, built in Go.
It provides a built-in terminal UI (TUI) for interactive use and plain text output for CI/CD pipelines and scripting.
lstk handles the full emulator lifecycle: authentication, pulling the Docker image, starting, stopping, and restarting the container, streaming logs, and checking status.
It can also save and load emulator state — as local snapshots, Cloud Pods, or in your own S3 bucket — reset running state, and manage the on-disk volume.
It proxies your existing tooling — the AWS and Azure CLIs, Terraform, AWS CDK, and the AWS SAM CLI — so they run against LocalStack with no per-tool wrapper, and it runs Git-style lstk-<name> extensions.
Running lstk with no arguments takes you through the entire startup flow automatically.
Prerequisites
Section titled “Prerequisites”- Docker installed and running.
- A LocalStack account with a license, and
lstkhandles authentication for you (see Authentication).
Installation
Section titled “Installation”brew install localstack/tap/lstkHomebrew also installs shell completions for bash, zsh, and fish automatically.
npm install -g @localstack/lstkDownload the binary for your platform from GitHub Releases, extract it, and place it on your PATH.
Verify the installation:
lstk --versionUpdating
Section titled “Updating”lstk can update itself.
It detects how it was originally installed (Homebrew, npm, or binary) and uses the matching update method:
# Check for updates without installinglstk update --check
# Update to the latest versionlstk updateSee the update command for details, including the start-time update notification.
Quick start
Section titled “Quick start”lstkRunning lstk without arguments performs the full startup sequence: authenticates you automatically, pulls the latest image if needed, and starts the LocalStack container.
In an interactive terminal it launches the TUI; in a non-interactive environment it prints plain text output.
On the very first interactive run, lstk prompts you to pick which emulator to run (AWS, Snowflake, or Azure) and writes your choice to config.toml.
See Emulator types for the available options.
For CI or headless environments, set LOCALSTACK_AUTH_TOKEN and use --non-interactive:
LOCALSTACK_AUTH_TOKEN=<your-ci-auth-token> lstk --non-interactiveCI environments require a CI Auth Token; a personal Developer Auth Token cannot be used there.
Authentication
Section titled “Authentication”lstk resolves your auth token in the following order:
- System keyring: a token stored by a previous
lstk login. LOCALSTACK_AUTH_TOKENenvironment variable: used only when the keyring has no token.- Browser login: triggered automatically in interactive mode when neither of the above provides a token.
Logging in
Section titled “Logging in”lstk loginOpens a browser window for authentication and stores the resulting token in your system keyring.
This command requires an interactive terminal.
See the login command for the full flow and the endpoints it uses.
Logging out
Section titled “Logging out”lstk logoutRemoves the stored credentials from the system keyring and the file-based fallback, and clears the cached license.
logout cannot clear a token supplied via LOCALSTACK_AUTH_TOKEN; if you authenticated that way, unset the variable instead.
See the logout command for the full behavior.
File-based token storage
Section titled “File-based token storage”On systems where the system keyring is unavailable, lstk automatically falls back to storing the token in a file (<config-dir>/auth-token, mode 0600).
You can force file-based storage by setting:
export LSTK_KEYRING=fileConfiguration
Section titled “Configuration”lstk uses a TOML configuration file, created automatically on first run.
Config file search order
Section titled “Config file search order”lstk uses the first config.toml it finds in this order:
./.lstk/config.toml: project-local config in the current directory.$HOME/.config/lstk/config.toml: user config (created here if$HOME/.config/exists).- OS default:
- macOS:
$HOME/Library/Application Support/lstk/config.toml - Windows:
%AppData%\lstk\config.toml - Linux:
$XDG_CONFIG_HOME/lstk/config.tomlor$HOME/.config/lstk/config.toml
- macOS:
On first run, the config is created at path #2 if $HOME/.config/ already exists; otherwise at the OS default (#3).
To see the active config file path:
lstk config pathTo use a specific config file:
lstk --config /path/to/config.toml startDefault configuration
Section titled “Default configuration”The default config.toml created on first run:
[[containers]]type = "aws" # Emulator type. Supported: "aws", "snowflake", "azure"tag = "latest" # Docker image tag, e.g. "latest", "2026.4"port = "4566" # Host port the emulator will be accessible on# image = "" # Override the default Docker image (internal registry mirror or offline image)# volume = "" # Host directory for persistent state (default: OS cache dir)# volumes = [] # Docker-style "host:container[:ro]" bind mounts (see below)# snapshot = "" # Snapshot REF auto-loaded after the AWS emulator starts (e.g. "pod:my-baseline")# env = [] # Named environment profiles to apply (see [env.*] sections below)Config field reference
Section titled “Config field reference”| Field | Type | Default | Description |
|---|---|---|---|
type |
string | "aws" |
Emulator type. One of "aws", "snowflake", "azure". Run a single [[containers]] block at a time. See Emulator types. |
tag |
string | "latest" |
Docker image tag ("latest", "2026.4", etc.). Useful for pinning a specific version. Zero-padded months ("2026.04") are normalized to "2026.4". |
port |
string | "4566" |
Host port the emulator listens on (1–65535). The in-container port is always 4566. |
image |
string | (unset) | Override the default Docker image, e.g. an internal-registry mirror or a locally loaded offline image. If it already carries a tag, tag is dropped; otherwise tag (or latest) is appended. When unset, the default localstack/<product> image is used. |
volume |
string | (OS cache) | Host directory for persistent emulator state (mounted at /var/lib/localstack). Defaults to <os-cache>/lstk/volume/<container-name>. Used verbatim (no path resolution). |
volumes |
string[] | [] |
Docker-style "host:container[:ro]" bind mounts (e.g. Snowflake init hooks). May also carry the persistence mount (the entry targeting /var/lib/localstack); relative host sources are resolved against the config file’s directory and a leading ~/ is expanded. See Volume mounts. |
snapshot |
string | (unset) | Snapshot REF (a pod:<name>, local path, or s3:// location) auto-loaded after the emulator starts. AWS emulator only. See Auto-loading a snapshot on start. |
env |
string[] | [] |
List of named environment profiles to inject into the container (see below). |
Emulator types
Section titled “Emulator types”lstk can run more than one kind of emulator.
The type field in your config.toml selects which one:
| Type | Docker image | Description |
|---|---|---|
aws |
localstack/localstack-pro |
LocalStack AWS emulator (default). |
snowflake |
localstack/snowflake |
LocalStack Snowflake emulator. |
azure |
localstack/localstack-azure |
LocalStack Azure emulator. |
On the first interactive run, lstk prompts you to pick an emulator (a for AWS, s for Snowflake, z for Azure) and writes your choice to config.toml.
In non-interactive mode the default aws emulator is used.
Lifecycle commands operate on the emulators defined in your config.toml.
Run a single [[containers]] block at a time.
The AWS-specific commands — status resources, reset, the aws CLI proxy, the IaC proxies (terraform, cdk, sam), and setup aws — require an aws emulator; az and setup azure require an azure emulator.
snapshot (save/load/list/remove/show) works with any emulator, but prints an experimental-support warning for the Snowflake and Azure emulators.
Passing environment variables to the container
Section titled “Passing environment variables to the container”Define reusable environment profiles under [env.<name>] and reference them in your container config:
[[containers]]type = "aws"tag = "latest"port = "4566"env = ["debug", "ci"]
[env.debug]DEBUG = "1"ENFORCE_IAM = "1"PERSISTENCE = "1"
[env.ci]SERVICES = "s3,sqs"EAGER_SERVICE_LOADING = "1"When lstk start runs, the key-value pairs from each referenced profile are injected as environment variables into the LocalStack container.
Keys are uppercased automatically.
In addition to your custom profiles, lstk always injects several variables into the container.
See Container-injected variables for the full list.
Volume mounts
Section titled “Volume mounts”Each [[containers]] block accepts a volumes list of Docker-style "host:container[:ro]" bind specs, in addition to the singular volume field.
This is useful for mounting init hooks (for example, Snowflake boot/start/ready/shutdown scripts under /etc/localstack/init) or any other host directory into the emulator.
[[containers]]type = "snowflake"port = "4566"volumes = [ "./init/ready.d:/etc/localstack/init/ready.d", # init hooks "./data:/var/lib/localstack", # persistence mount "./seed:/seed:ro", # read-only mount]Resolution rules:
- Relative host sources (
./data) are resolved against the directory of the config file that declared them, and a leading~/is expanded. This is required because the Docker SDK treats a non-absolute source as a named volume rather than a bind mount. - The entry whose container target is
/var/lib/localstackdefines the persistence directory — the same onelstk volume pathandlstk volume clearact on. Precedence: avolumesentry targeting/var/lib/localstack→ the legacyvolumefield → the default OS cache directory. volumeandvolumesoverlap only for the persistence mount. The legacyvolumevalue is used verbatim (no path resolution);volumessources are resolved. Setting the persistence directory via bothvolumeand avolumesentry with different sources is a validation error.- The persistence directory is created automatically if missing; other
volumessources are expected to already exist (they are typically files, such as init hooks) andlstkerrors if one is missing.
Using a project-local config
Section titled “Using a project-local config”Place a .lstk/config.toml in your project directory.
When you run lstk from that directory, the local config takes precedence over the global one.
This lets each project pin its own emulator type, image tag, and environment profiles.
For example, a project that targets the Snowflake emulator can keep its own config:
[[containers]]type = "snowflake"port = "4566"An AWS project might instead pin a specific image tag and enable a debug profile:
[[containers]]type = "aws"tag = "2026.4"port = "4566"env = ["dev"]
[env.dev]DEBUG = "1"PERSISTENCE = "1"Commands
Section titled “Commands”lstk uses a flat command structure.
Running lstk with no command is equivalent to lstk start.
Start the LocalStack emulator.
Launches the TUI in interactive terminals and prints plain output otherwise.
lstk start launches the emulator defined in the first [[containers]] entry of the resolved config.toml (not necessarily AWS).
lstk startlstk start --persistlstk start --non-interactive| Option | Description |
|---|---|
--persist |
Persist emulator state across restarts (sets LOCALSTACK_PERSISTENCE=1 in the container) |
--snapshot <ref> |
Snapshot REF to auto-load once the emulator starts, overriding the snapshot config field for this run |
--no-snapshot |
Skip auto-loading the configured snapshot for this run |
--non-interactive |
Disable the interactive TUI and use plain output (a global flag) |
Host environment variables prefixed with LOCALSTACK_ are forwarded to the emulator on start (the host LOCALSTACK_AUTH_TOKEN is dropped so it cannot override the token lstk resolves). See Container-injected variables.
By default the emulator starts with a fresh state on every run.
Pass --persist to keep data across restarts: lstk injects LOCALSTACK_PERSISTENCE=1 into the container so state is written to the mounted volume and reloaded on the next start.
When persistence is active, the AWS emulator’s startup summary includes a • Persistence: Enabled line.
# Start with persistent statelstk start --persistAuto-loading a snapshot on start
Section titled “Auto-loading a snapshot on start”The AWS emulator can auto-load a snapshot as it comes up.
Set the snapshot field on the AWS [[containers]] block to any load REF — a pod:<name> Cloud Pod, a local snapshot path, or an s3:// location:
[[containers]]type = "aws"port = "4566"snapshot = "pod:my-baseline"The snapshot is loaded only when the emulator is freshly started this run (it is skipped when the emulator is already running), mirroring v1’s AUTO_LOAD_POD.
Override the configured REF for a single run with lstk start --snapshot <ref>, or skip auto-loading entirely with lstk start --no-snapshot.
An invalid REF fails before the emulator starts.
snapshot save never writes this field back — it is set manually.
Stop the running LocalStack emulator.
Stops every emulator container defined in the resolved config.toml (the [[containers]] entries), with a 30-second stop timeout per container.
lstk stoplstk stop --non-interactivestop fails fast if the Docker runtime is not healthy (for example, Docker is not running), or if a configured emulator is not currently running (LocalStack is not running).
In an interactive terminal it shows an animated “Stopping LocalStack…” spinner and a styled confirmation; in non-interactive mode it prints the same progress and result as plain text.
restart
Section titled “restart”Stop and restart the LocalStack emulator.
Performs a stop of the running emulator followed by a fresh start, using the same auth, config, and Docker settings as start.
Launches the TUI in interactive terminals and prints plain output otherwise.
lstk restartlstk restart --persist| Option | Description |
|---|---|
--persist |
Persist emulator state across the restart |
By default, emulator state is not retained across the restart and the container starts clean.
Pass --persist to keep the emulator’s state so it survives the restart.
status
Section titled “status”Show the status of a running emulator and its deployed resources.
Before contacting the emulator, lstk checks that the Docker runtime is healthy; if it is not, the command reports runtime not healthy and exits with a non-zero status.
lstk statuslstk --non-interactive statusFor each emulator configured in your config.toml (the [[containers]] entries), status reports whether it is running and, if so, prints an instance summary:
LocalStack AWS Emulator is running• Endpoint: localhost:4566• Persistence: Enabled• Container: localstack-aws• Version: 4.0.0• Uptime: 1h 12m 4s- Endpoint is the live
host:port, queried from Docker, so it stays correct even if the configuredportwas changed while the container kept running. - Persistence appears only for the AWS emulator and only when persistence is enabled.
- Uptime is computed from the container’s start time and is omitted if it cannot be determined.
If an emulator is not running, status prints an error and exits non-zero without checking the remaining emulators:
LocalStack AWS Emulator is not running
Start LocalStack: lstk See help: lstk -hFor the AWS emulator, status additionally lists deployed resources.
When resources exist it prints a summary line followed by a table; when none exist it prints No resources deployed.
~ 3 resources · 2 services
Service Resource Region AccountS3 my-bucket us-east-1 000000000000SQS my-queue us-east-1 000000000000In an interactive terminal the output is rendered through the TUI; in non-interactive mode (or with --non-interactive) the same content is printed as plain text, with the resource table shown at full width when stdout is not a TTY.
The Snowflake and Azure emulators show the instance summary only and never report resources.
Show or stream emulator logs.
lstk logs [options]| Option | Description |
|---|---|
--follow, -f |
Stream logs in real-time. Without this flag, lstk prints the currently available logs and exits. |
--verbose, -v |
Show all logs without filtering. By default, lstk drops noisy lines (internal request logs, provider chatter); --verbose shows every line verbatim. |
By default, lstk logs reads from the first configured emulator container and applies a noise filter.
In an interactive terminal, lines are color-coded by log level (DEBUG, INFO, WARN, ERROR); in non-interactive mode, raw log lines are written to stdout.
Example:
# Print current filtered logs and exitlstk logs
# Stream filtered logs in real-timelstk logs --follow
# Stream all logs without filteringlstk logs --follow --verboseRun AWS CLI commands against the running LocalStack emulator.
lstk aws proxies your host aws CLI with the endpoint, credentials, and region pre-configured, so you don’t have to pass --endpoint-url or set test credentials yourself.
lstk aws s3 lslstk aws sqs list-queueslstk aws s3 mb s3://my-bucketIt is equivalent to running:
aws --endpoint-url http://localhost:4566 <args>with AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_DEFAULT_REGION set automatically.
Everything after lstk aws is forwarded verbatim to the host aws binary, including AWS CLI flags such as --region or --output.
The exit code and stdout/stderr of the underlying aws process are passed through unchanged, so piping and interactive subcommands work as expected.
| Option | Description |
|---|---|
--non-interactive |
Suppress the loading spinner. Unlike other commands, this flag is stripped before invoking aws (not forwarded). |
Credentials and region
Section titled “Credentials and region”lstk aws injects credentials in one of two ways:
- Profile mode: if a complete
localstackprofile exists in both~/.aws/configand~/.aws/credentials,lstkappends--profile localstackand letsawsread the region, credentials, and endpoint from that profile. - Profile-less mode: if the profile is not present,
lstkrunsawswithAWS_ACCESS_KEY_ID=test,AWS_SECRET_ACCESS_KEY=test, andAWS_DEFAULT_REGION=us-east-1injected only when those variables are not already set in your environment. In this mode it also prints an informational note:No AWS profile found, run 'lstk setup aws'.
Run lstk setup aws to create the localstack profile for use with the AWS CLI and SDKs.
Endpoint resolution
Section titled “Endpoint resolution”By default, lstk probes whether localhost.localstack.cloud resolves to 127.0.0.1 and uses localhost.localstack.cloud:<port> if so, otherwise it falls back to 127.0.0.1:<port>.
Set LOCALSTACK_HOST to override the host:port used to reach LocalStack and skip the DNS probe.
The port comes from the AWS container’s port in config.toml (default 4566).
Run Azure CLI commands against the running LocalStack Azure emulator.
lstk az <args> runs az <args> with an isolated AZURE_CONFIG_DIR in which a custom Azure cloud (LocalStack) is registered against LocalStack’s endpoints, so your global ~/.azure configuration is left untouched and plain az keeps talking to real Azure.
lstk az group listlstk az storage account listRun lstk setup azure once before using this mode.
lstk az requires the az CLI on your PATH, a healthy Docker runtime, a running Azure emulator, and that *.localhost.localstack.cloud resolves to 127.0.0.1 (the Azure emulator serves its endpoints under that host). Set LOCALSTACK_HOST to override the host.
Everything after lstk az is forwarded verbatim to the host az binary; its exit code and stdout/stderr pass through unchanged.
az start-interception / az stop-interception
Section titled “az start-interception / az stop-interception”An opt-in second mode mutates your global ~/.azure configuration so plain az (in any terminal or script) targets LocalStack, then switches it back.
lstk az start-interception # global 'az' now targets LocalStacklstk az stop-interception # switch back to real Azurestart-interceptionregisters and activates theLocalStackcloud in~/.azureand disables instance discovery, so existingazscripts run unmodified against LocalStack. It is independent oflstk setup azure.stop-interceptionswitches the active cloud back toAzureCloud(override with--cloud <name>) and re-enables instance discovery — but only ifLocalStackis still the active cloud, to avoid clobbering an unrelated selection.
Because interception changes global state affecting every az invocation, prefer the isolated lstk az <args> mode unless a script must invoke plain az.
terraform
Section titled “terraform”Proxy Terraform commands to LocalStack, injecting LocalStack endpoints as AWS provider overrides so your existing configuration runs unchanged. Aliased as lstk tf.
lstk terraform initlstk terraform --region us-west-2 planlstk tf applylstk-specific flags must appear before the Terraform subcommand:
| Flag | Description |
|---|---|
--region <region> |
Deployment region (default us-east-1; falls back to AWS_REGION). |
--account <id> |
Target AWS account id, 12 digits (default test; falls back to AWS_ACCESS_KEY_ID). |
Commands that don’t contact AWS (fmt, validate, version, and init when no S3 backend is declared) run without a running emulator; everything else requires the AWS emulator to be running and Docker healthy.
Supported environment variables:
| Variable | Description |
|---|---|
AWS_ENDPOINT_URL |
Override the auto-resolved LocalStack endpoint. |
LSTK_TF_CMD |
Terraform binary to invoke (e.g. tofu; default terraform). |
LSTK_TF_OVERRIDE_FILE_NAME |
Provider-override file name (default localstack_providers_override.tf). |
LSTK_TF_DRY_RUN |
Generate the override file but do not run Terraform. |
AWS_REGION |
Fallback for --region. |
AWS_ACCESS_KEY_ID |
Fallback for --account. |
Proxy AWS CDK commands to the running LocalStack emulator.
Requires the AWS CDK CLI version 2.177.0 or newer on your PATH.
lstk cdk bootstraplstk cdk --region us-west-2 deploylstk cdk synthCDK always targets the default LocalStack account 000000000000; there is no --account flag (passing one is an error). The --region <region> flag (default us-east-1, falling back to AWS_REGION) must appear before the CDK action.
Offline subcommands (e.g. synth) run without a running emulator; deploy-time commands require the AWS emulator to be running.
Supported environment variables:
| Variable | Description |
|---|---|
AWS_ENDPOINT_URL |
Override the auto-resolved LocalStack endpoint. |
AWS_ENDPOINT_URL_S3 |
Override the auto-derived S3 endpoint. |
LSTK_CDK_CMD |
CDK binary to invoke (default cdk). |
AWS_REGION |
Fallback for --region. |
Proxy AWS SAM CLI commands to the running LocalStack emulator.
Requires the AWS SAM CLI version 1.95.0 or newer on your PATH (older versions ignore AWS_ENDPOINT_URL and would target real AWS).
lstk sam buildlstk sam --region us-west-2 deploylstk sam validatelstk-specific flags must appear before the SAM action:
| Flag | Description |
|---|---|
--region <region> |
Deployment region (default us-east-1; falls back to AWS_REGION). |
--account <id> |
Target AWS account id, 12 digits (default 000000000000; falls back to AWS_ACCESS_KEY_ID). |
Offline subcommands (e.g. build, validate) run without a running emulator; deploy-time commands require the AWS emulator to be running.
Supported environment variables:
| Variable | Description |
|---|---|
AWS_ENDPOINT_URL |
Override the auto-resolved LocalStack endpoint. |
AWS_ENDPOINT_URL_S3 |
Override the S3 endpoint. |
LSTK_SAM_CMD |
SAM binary to invoke (default sam). |
AWS_REGION |
Fallback for --region. |
AWS_ACCESS_KEY_ID |
Fallback for --account. |
snapshot
Section titled “snapshot”Manage emulator snapshots.
A snapshot captures the running emulator’s state — as a local file on disk, a Cloud Pod on the LocalStack platform, or an object in your own S3 bucket.
The snapshot command groups five subcommands — save, load, list, remove, and show. The first two are also exposed as the top-level aliases lstk save and lstk load.
snapshot save
Section titled “snapshot save”Save a snapshot of the running emulator’s state. The emulator must already be running; this command does not auto-start it.
# Auto-named snapshot file in the current directorylstk snapshot save
# Save to a specific local pathlstk snapshot save ./my-snapshot
# Save to a Cloud Pod on the LocalStack platform (requires auth)lstk snapshot save pod:my-baseline
# Save to your own S3 bucket (pod name optional, auto-generated when omitted)lstk snapshot save my-pod s3://my-bucket/prefixlstk snapshot save my-pod s3://my-bucket/prefix --profile my-aws-profileThe optional [destination] argument takes one of these forms:
| Destination | Description |
|---|---|
| (omitted) | Auto-generates a timestamped .snapshot file in the current directory. |
| local path | Writes a snapshot file to that path (the .snapshot extension is forced). |
pod:<name> |
Saves a Cloud Pod to the LocalStack platform. Requires authentication. |
s3://bucket/prefix |
Saves into your own S3 bucket. The pod name is a separate positional (auto-generated when omitted). |
Pod operations require an auth token (LOCALSTACK_AUTH_TOKEN or a prior lstk login); local-file snapshots do not.
| Option | Description |
|---|---|
--profile <name> |
AWS profile to read S3 credentials from (S3 destinations only). |
For S3 destinations, credentials follow AWS CLI precedence: --profile <name> wins, otherwise the static AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY (with optional AWS_SESSION_TOKEN), otherwise the profile named by AWS_PROFILE. Only static credentials are supported (no SSO, assume-role, or credential-process). Never put credentials in the URL. See S3 remotes.
snapshot load
Section titled “snapshot load”Load a snapshot into the emulator, auto-starting it first if it is not already running.
# Load a local snapshot by path or namelstk snapshot load my-baselinelstk snapshot load ./checkpoint
# Load from a Cloud Pod (requires auth)lstk snapshot load pod:my-baseline
# Load from your own S3 bucket (pod name required)lstk snapshot load my-pod s3://my-bucket/prefix --profile my-aws-profile
# Control how the snapshot merges with running statelstk snapshot load pod:my-baseline --merge=overwriteThe REF argument is required and identifies a local path/name, a pod:<name> Cloud Pod, or (with a separate pod-name positional) an s3:// location. Older .zip snapshots saved by earlier lstk versions are still accepted.
| Option | Description |
|---|---|
--merge <strategy> |
How the loaded state combines with running state. One of account-region-merge (default), overwrite, service-merge. |
--profile <name> |
AWS profile to read S3 credentials from (S3 sources only; see S3 remotes). |
account-region-merge(default): the snapshot wins on any(service, account, region)overlap.overwrite: running state is reset first, then the snapshot is imported onto a clean state.service-merge: the snapshot wins per resource; non-overlapping resources are combined.
The aliases behave identically:
lstk save pod:my-baselinelstk load ./checkpointsnapshot list
Section titled “snapshot list”List the Cloud Pod snapshots available on the LocalStack platform.
By default, only snapshots you created are listed; pass --all to include every snapshot in your organization.
This subcommand operates on Cloud Pods, so it requires authentication.
# Snapshots you createdlstk snapshot list
# Every snapshot in your organizationlstk snapshot list --all
# List snapshots in your own S3 bucket (requires a running emulator)lstk snapshot list s3://my-bucket/prefix --profile my-aws-profile| Option | Description |
|---|---|
--all |
List all snapshots in your organization, not just your own. |
--profile <name> |
AWS profile to read S3 credentials from (S3 listings only). |
snapshot remove
Section titled “snapshot remove”Delete a Cloud Pod snapshot from the LocalStack platform.
Only cloud snapshots (the pod: prefix) can be removed; local snapshots are plain files you delete yourself.
This operation cannot be undone.
lstk snapshot remove pod:my-baseline
# Skip the confirmation prompt (required in non-interactive mode)lstk snapshot remove pod:my-baseline --forceThe required REF argument must be a pod:<name> Cloud Pod reference.
| Option | Description |
|---|---|
--force |
Skip the confirmation prompt. Required when running non-interactively. |
snapshot show
Section titled “snapshot show”Show metadata for a single Cloud Pod snapshot on the LocalStack platform: name, created date, size, LocalStack version, message, services, and per-service resource counts (resource counts render only when the platform has them for that snapshot). Cloud-only and requires authentication.
lstk snapshot show pod:my-baselineThe required REF argument must be a pod:<name> Cloud Pod reference.
S3 remotes
Section titled “S3 remotes”snapshot save, load, and list can target your own S3 bucket with an s3://bucket/prefix location.
The pod name (the snapshot’s identity within the bucket) is a positional argument separate from the s3:// location — required for load, auto-generated for save when omitted, and unused for list.
- Credentials follow AWS CLI precedence:
--profile <name>wins, otherwise staticAWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY(with optionalAWS_SESSION_TOKEN), otherwise the profile named byAWS_PROFILE. Only static credentials are supported (no SSO, assume-role, or credential-process). Credentials are never accepted in the URL. - The emulator performs the transfer, not the CLI; credentials are passed as ephemeral parameters on each operation and are never persisted.
- Before each operation,
lstkruns a bucket-existence pre-flight check and errors out rather than letting the emulator auto-create a bucket on a typo. remove,show, and snapshot versions are not yet supported on S3 remotes; ORAS and other remote types are not supported.
Discard the running AWS emulator’s in-memory state (all created resources such as S3 buckets and Lambda functions are dropped). The emulator keeps running; only its state is cleared.
lstk resetlstk reset --force| Option | Description |
|---|---|
--force |
Skip the confirmation prompt. Required in non-interactive mode. |
In interactive mode, reset prompts for confirmation before clearing state.
In non-interactive mode it fails unless --force is passed:
reset requires confirmation; use --force to skip in non-interactive modevolume
Section titled “volume”Manage the emulator volume: the host directory that holds persistent state such as certificates, downloaded tools, and persistence data.
lstk volume pathlstk volume clear [options]volume path
Section titled “volume path”Prints the resolved volume directory for every emulator in your config, one per line.
With the default config (a single aws emulator) it prints one path.
Each path is the container’s configured volume value, or the default OS cache location if volume is unset (~/Library/Caches/lstk/volume/localstack-aws on macOS, ~/.cache/lstk/volume/localstack-aws on Linux).
# Print the volume directory for each configured emulatorlstk volume pathvolume clear
Section titled “volume clear”Removes all data from the emulator volume directory, resetting cached state.
It operates on all configured emulators by default, or a single one with --type.
Before clearing, it lists each target as <emulator>: <path> (<size>).
| Option | Description |
|---|---|
--force |
Skip the confirmation prompt |
--type <type> |
Clear only the emulator of this type |
# Clear all configured emulator volumes (prompts for confirmation)lstk volume clear
# Clear only the AWS emulator volumelstk volume clear --type aws
# Skip the confirmation promptlstk volume clear --force
# Clear without prompting in a non-interactive environmentlstk volume clear --type snowflake --forceIn an interactive terminal, lstk volume clear prompts Clear volume data? This cannot be undone before deleting anything; choosing NO or pressing Ctrl+C cancels with no changes.
In non-interactive mode, --force is required, otherwise the command fails with volume clear requires confirmation; use --force to skip in non-interactive mode.
Authenticate with LocalStack via a browser-based device authorization flow and store the resulting credential in your system keyring. This command requires an interactive terminal.
lstk loginlstk opens your default browser to the LocalStack Web Application, shows a one-time code, and waits for you to approve the request.
If the browser cannot open automatically, lstk prints the URL to visit manually.
On success it stores the license token returned by the platform (not the raw browser bearer token).
If you are already authenticated — either LOCALSTACK_AUTH_TOKEN is set or a token already exists in storage — login prints You're already logged in and exits without starting a new flow.
In non-interactive mode (piped output, CI, or --non-interactive), login fails with login requires an interactive terminal.
The --config <path> flag selects which config.toml is loaded, which affects keyring, web_app_url, and api_endpoint resolution.
The credential is written to the system keyring (service lstk, key lstk.auth-token).
When the keyring is unavailable — or LSTK_KEYRING=file is set — lstk stores it in a file at <config-dir>/auth-token (mode 0600) instead.
Endpoints used by the flow can be overridden via config or environment:
| Config key | Env var | Default | Description |
|---|---|---|---|
keyring |
LSTK_KEYRING |
(system keyring) | Set to file to force file-based token storage instead of the OS keyring. |
web_app_url |
LSTK_WEB_APP_URL |
https://app.localstack.cloud |
Base URL used to build the browser authorization link. |
api_endpoint |
LSTK_API_ENDPOINT |
https://api.localstack.cloud |
LocalStack platform API endpoint used for the device flow and license token. |
# Force file-based token storage during loginLSTK_KEYRING=file lstk login
# Use a specific config filelstk --config ./.lstk/config.toml loginlogout
Section titled “logout”Remove stored authentication credentials.
lstk logoutlstk logout --non-interactivelogout deletes the auth token from your system keyring (falling back to the file-based token at <config-dir>/auth-token when the keyring is unavailable or LSTK_KEYRING=file is set) and removes the cached license file.
On success it prints Logged out successfully.
The outcome depends on how you are authenticated:
| Situation | Behavior |
|---|---|
A token is stored (from lstk login) |
The token is deleted from the keyring and file fallback, the cached license is removed, and lstk prints Logged out successfully. |
No stored token, but LOCALSTACK_AUTH_TOKEN is set |
Nothing is deleted. lstk prints a note that you are authenticated via the environment variable and to unset it to log out. |
No stored token and no LOCALSTACK_AUTH_TOKEN |
lstk prints Not currently logged in and exits successfully. |
Set up CLI integration for an emulator type.
lstk setup is a grouping command with no action of its own; the work is done by its subcommands (aws and azure).
lstk setup awslstk setup azuresetup aws
Section titled “setup aws”Create or update a localstack profile in ~/.aws/config and ~/.aws/credentials so the AWS CLI and SDKs can target LocalStack.
lstk setup awslstk setup aws --force| Option | Description |
|---|---|
--force |
Skip the confirmation prompt and overwrite an existing localstack profile whose values differ. |
It writes the following profile (existing unrelated profiles are preserved):
[profile localstack]region = us-east-1output = jsonendpoint_url = http://localhost.localstack.cloud:4566
# ~/.aws/credentials[localstack]aws_access_key_id = testaws_secret_access_key = testAfterwards, target LocalStack by passing --profile localstack or exporting AWS_PROFILE:
export AWS_PROFILE=localstackaws s3 lsThe endpoint host is resolved automatically: lstk probes localhost.localstack.cloud and uses it when it resolves to 127.0.0.1, otherwise it falls back to 127.0.0.1.
Set LOCALSTACK_HOST to override the host and port written into the profile.
The port comes from your AWS emulator’s configured port (default 4566); if no aws emulator is configured, the command fails with no aws emulator configured.
If the localstack profile is already configured correctly, lstk reports LocalStack AWS profile is already configured. and makes no changes.
On an interactive terminal, setup aws prompts (Y/n) before writing. Overwriting an existing localstack profile whose values differ requires --force (which also skips the prompt); writing a fresh profile, completing a partial one, or leaving an already-correct profile unchanged never needs it.
setup azure
Section titled “setup azure”Prepare an isolated Azure CLI config directory (under the lstk config dir, via AZURE_CONFIG_DIR) that routes lstk az commands to the LocalStack Azure emulator.
It registers a custom Azure cloud (LocalStack) pointing at LocalStack’s Azure endpoints, activates it, disables Azure CLI instance discovery and telemetry, and performs a one-time dummy service-principal login.
Your global ~/.azure configuration is left untouched.
lstk setup azureRequires the az CLI on your PATH and a running LocalStack Azure emulator.
Run this once; afterwards use lstk az <args> to run Azure CLI commands against LocalStack.
config
Section titled “config”Manage CLI configuration.
config has no behavior of its own; run it with a subcommand.
config path
Section titled “config path”Print the resolved path to the active config.toml.
lstk config pathThis subcommand is read-only: it never creates or initializes a config file.
If --config <path> is set, it prints that path verbatim.
Otherwise it prints the already-loaded config path, the first existing config in the search order, or the path where a config would be created on first run.
config profile
Section titled “config profile”Write a LocalStack AWS CLI profile into ~/.aws/config and ~/.aws/credentials, pointing at your configured emulator.
lstk config profile # prefer: lstk setup awsRequires an interactive terminal. In non-interactive mode it fails with:
config profile requires an interactive terminalThe generated profile uses the host from the LOCALSTACK_HOST environment variable (when set) and your configured containers, identical to setup aws.
update
Section titled “update”Check for and apply updates to the lstk CLI itself.
lstk auto-detects how it was installed (Homebrew, npm, or direct binary) and updates using that same method.
Development builds (version dev) are skipped, and updates are checked against the latest GitHub release.
lstk update [options]| Option | Description |
|---|---|
--check |
Check for updates without installing them |
--non-interactive |
Use plain output instead of the TUI (update logic unchanged) |
Examples:
# Check for updates without installinglstk update --check
# Update to the latest versionlstk update
# Update with plain (non-TUI) outputlstk update --non-interactiveBy install method:
- Homebrew (binary under a
Caskroompath): runsbrew upgrade localstack/tap/lstk. - npm (binary under
node_modules): runsnpm install -g @localstack/lstk@latest. - Binary (anything else): downloads the release asset for your OS/arch from GitHub, extracts it, and replaces the running executable in place.
With --check, lstk only reports whether a newer version is available and exits without downloading or installing anything.
Update notification on start
Section titled “Update notification on start”Separately from lstk update, lstk checks for a newer version when you run lstk start (the default command), using a short timeout that fails silently if GitHub is unreachable.
In an interactive terminal, when an update is available lstk prints the new version and a release-notes link, then prompts:
Update lstk to latest version?> Update now [U] Remind me next time [R] Skip this version [S]- Update now [U]: downloads and applies the update, then asks you to re-run your command.
- Remind me next time [R]: does nothing; you are reminded on the next run.
- Skip this version [S]: records the version in
config.tomlso you are not prompted about it again.
In non-interactive mode the notification is not a prompt — lstk emits a single note (Update available: <current> → <latest> (run lstk update)) and continues.
When you choose Skip this version, lstk writes the skipped version under a [cli] table:
[cli]update_skipped_version = "0.5.0"While this value matches the latest available version, the start-time update notification for that version is suppressed. This key is managed automatically and is not intended to be edited by hand.
completion
Section titled “completion”Generate shell completion scripts.
lstk completion [bash|zsh|fish|powershell]See Shell completions for setup instructions.
Global options
Section titled “Global options”These options are available for all commands:
| Option | Description |
|---|---|
--config <path> |
Path to a specific TOML config file |
--non-interactive |
Disable the interactive TUI, use plain output |
--persist |
Persist emulator state across restarts (on start/bare lstk and restart) |
--snapshot <ref> |
Snapshot REF to auto-load after start (on start/bare lstk; overrides config for the run) |
--no-snapshot |
Skip auto-loading the configured snapshot for the run (on start/bare lstk) |
-v, --version |
Print the version and exit |
-h, --help |
Print help and exit |
Interactive and non-interactive mode
Section titled “Interactive and non-interactive mode”lstk automatically selects its output mode:
- Interactive mode (TUI): used when both stdin and stdout are connected to a terminal.
Commands like
start,stop,restart,status,login,update, and the confirmation prompts ofreset/volume cleardisplay a Bubble Tea-powered terminal UI. - Non-interactive mode (plain text): used when the output is piped, redirected, or running in CI.
Force this in a TTY with
--non-interactive.
# Force plain output even in an interactive terminallstk --non-interactive startEnvironment variables
Section titled “Environment variables”The following environment variables configure lstk itself (not the LocalStack container):
| Variable | Description |
|---|---|
LOCALSTACK_AUTH_TOKEN |
Auth token for non-interactive runs or to skip browser login. Used when no keyring token is stored. |
LOCALSTACK_HOST |
Override the host (and optional port) used when resolving and printing the emulator endpoint, and when writing the AWS CLI profile. Bypasses the localhost.localstack.cloud DNS probe. |
LOCALSTACK_DISABLE_EVENTS |
Set to 1 to disable anonymous telemetry event reporting. |
DOCKER_HOST |
Override the Docker daemon socket (e.g. unix:///home/user/.colima/default/docker.sock). |
LSTK_KEYRING |
Set to file to force file-based token storage instead of the system keyring. |
LSTK_OTEL |
Set to 1 to enable OpenTelemetry trace export (disabled by default). See OpenTelemetry tracing. |
LSTK_GITHUB_TOKEN |
Optional GitHub token used when checking for or downloading lstk updates (raises GitHub API rate limits). |
LSTK_API_ENDPOINT |
Override the LocalStack platform API base URL. Default: https://api.localstack.cloud. |
LSTK_WEB_APP_URL |
Override the LocalStack Web Application URL used for browser login. Default: https://app.localstack.cloud. |
When DOCKER_HOST is not set, lstk tries the default Docker socket and then probes common alternatives (Colima at ~/.colima/default/docker.sock, OrbStack at ~/.orbstack/run/docker.sock).
When LSTK_OTEL is enabled, the standard OTEL_EXPORTER_OTLP_* environment variables are honored by the OpenTelemetry SDK.
Container-injected variables
Section titled “Container-injected variables”lstk injects several environment variables into the LocalStack container on every start, in addition to any profiles you configure:
| Variable | Default value | Description |
|---|---|---|
LOCALSTACK_AUTH_TOKEN |
(your resolved token) | Passed from the CLI to activate the license. |
GATEWAY_LISTEN |
:4566,:443 |
Ports the emulator binds inside the container. |
MAIN_CONTAINER_NAME |
localstack-aws |
Container name for internal references. |
LOCALSTACK_HOST |
localhost.localstack.cloud:<host port> |
Hostname/port the emulator advertises. |
LOCALSTACK_PERSISTENCE |
1 (only with --persist) |
Enables state persistence across restarts. |
When a Docker socket is detected it is bind-mounted into the container and DOCKER_HOST=unix:///var/run/docker.sock is injected so the emulator can spawn its own containers.
lstk also forwards host environment variables matching CI and LOCALSTACK_* (the host LOCALSTACK_AUTH_TOKEN is dropped so it cannot override the token resolved by lstk).
The container also gets port mappings for 4566, 443, and the service port range 4510-4559.
OpenTelemetry tracing
Section titled “OpenTelemetry tracing”lstk can export traces of its own command execution over OTLP/HTTP.
Tracing is disabled by default.
Enable it with:
LSTK_OTEL=1 lstk startWhen enabled, every command is wrapped in a span (e.g. lstk.start) recording the exit code and any error.
lstk does not hardcode an export target, so the OpenTelemetry Go SDK reads the standard OTEL_EXPORTER_OTLP_* environment variables automatically (default target: OTLP/HTTP at localhost:4318).
You need an OTLP-compatible backend running to receive the traces.
Logging
Section titled “Logging”lstk writes its own diagnostic logs to lstk.log in the same directory as the active config file.
This is separate from the LocalStack container logs (which you view with lstk logs).
- The log file is created automatically and appended to across runs.
- When the file exceeds 1 MB, it is cleared on the next run.
- Use
lstk config pathto find the config directory;lstk.logsits alongsideconfig.toml.
Shell completions
Section titled “Shell completions”lstk includes completion scripts for bash, zsh, fish, and powershell.
If you installed via Homebrew, completions are set up automatically.
For manual setup:
# Load in current sessionsource <(lstk completion bash)
# Persist (Linux)lstk completion bash > /etc/bash_completion.d/lstk
# Persist (macOS with Homebrew)lstk completion bash > $(brew --prefix)/etc/bash_completion.d/lstk# Load in current sessionsource <(lstk completion zsh)
# Persist (Linux)lstk completion zsh > "${fpath[1]}/_lstk"
# Persist (macOS with Homebrew)lstk completion zsh > $(brew --prefix)/share/zsh/site-functions/_lstk# Load in current sessionlstk completion fish | source
# Persistlstk completion fish > ~/.config/fish/completions/lstk.fishRestart your shell after persisting completions.
Extensions
Section titled “Extensions”lstk supports Git-style extensions.
When lstk <name> is not a built-in command or alias, lstk resolves and runs an external lstk-<name> executable, forwarding all arguments after <name> verbatim, passing stdin/stdout/stderr through, and propagating the child’s exit code.
# Runs the lstk-hello executable, forwarding "world"lstk hello worldBuilt-in commands always take precedence — extension dispatch happens only for an otherwise-unknown command.
Resolution order is built-ins → the directory containing the lstk executable (so extensions bundled alongside lstk are found through npm/Homebrew shims) → your PATH.
There is no manifest: any resolvable lstk-<name> is the <name> extension.
lstk conveys runtime context to the extension through two environment variables:
| Variable | Description |
|---|---|
LSTK_EXT_API_VERSION |
A flat integer the extension can check before parsing the context. |
LSTK_EXT_CONTEXT |
A JSON object with configDir, an optional authToken, nonInteractive, and an emulators array of {type, endpoint, port} (empty when none are running). |
Can I use lstk with Docker Compose?
Section titled “Can I use lstk with Docker Compose?”No. lstk manages its own Docker container directly.
If you use a docker-compose.yml to run LocalStack, you do not need lstk, and vice versa.
Do not mix lstk start with a Docker Compose setup; they are separate, independent methods.
For Docker Compose configuration, see the Docker Compose installation guide.
Which Docker image does lstk use?
Section titled “Which Docker image does lstk use?”It depends on the emulator type configured in your config.toml.
The AWS emulator uses localstack/localstack-pro, the Snowflake emulator uses localstack/snowflake, and the Azure emulator uses localstack/localstack-azure.
All require a valid auth token (including the free Hobby tier).
See Emulator types.
How do I pass configuration options like DEBUG or PERSISTENCE to the container?
Section titled “How do I pass configuration options like DEBUG or PERSISTENCE to the container?”Use environment profiles in your config.toml.
Define the variables under an [env.<name>] section and reference that name in the env list of your container config.
See Passing environment variables to the container for details.
How do I save and restore emulator state?
Section titled “How do I save and restore emulator state?”Use lstk snapshot save to capture the running AWS emulator’s state to a local file or a Cloud Pod, and lstk snapshot load (or the lstk save / lstk load aliases) to restore it.
To drop in-memory state without writing a snapshot, use lstk reset.
How do I pin a specific LocalStack version?
Section titled “How do I pin a specific LocalStack version?”Set the tag field in your config.toml to a specific version tag:
[[containers]]type = "aws"tag = "2026.4"port = "4566"Troubleshooting
Section titled “Troubleshooting”Port 443 already in use
Section titled “Port 443 already in use”By default, LocalStack binds to both port 4566 and port 443 inside the container (controlled by the GATEWAY_LISTEN variable).
On some systems, particularly Windows with Hyper-V, IIS, or VPN software, port 443 may already be in use.
Symptoms:
failed to start LocalStack: Error response from daemon: ports are not available:exposing port TCP 127.0.0.1:443 -> 127.0.0.1:0: listen tcp4 127.0.0.1:443: bind:address already in useFix: Override GATEWAY_LISTEN to bind only to port 4566:
[[containers]]type = "aws"tag = "latest"port = "4566"env = ["nossl"]
[env.nossl]GATEWAY_LISTEN = "0.0.0.0:4566"This tells the container to skip the port 443 binding entirely.
Docker is not running
Section titled “Docker is not running”lstk requires a running Docker daemon.
If Docker is not reachable, you will see an error like:
Error: runtime not healthyFix: Start Docker Desktop (macOS/Windows) or the Docker daemon (sudo systemctl start docker on Linux).
If you use Colima or OrbStack, make sure the VM is running.
You can also point lstk at a custom socket with DOCKER_HOST.
Authentication required in non-interactive mode
Section titled “Authentication required in non-interactive mode”When running without a TTY (e.g. in CI), lstk cannot open a browser for login.
If no token is found in the keyring or environment, it fails:
authentication required: set LOCALSTACK_AUTH_TOKEN or run in interactive modeFix: Set the LOCALSTACK_AUTH_TOKEN environment variable before running lstk:
export LOCALSTACK_AUTH_TOKEN=<your-token>lstk --non-interactive startYou can find your auth token on the Auth Tokens page.
License validation failed
Section titled “License validation failed”If your auth token is invalid, expired, or not linked to an active license, the LocalStack container exits with a license error:
The license activation failed for the following reason:No credentials were found in the environment.Fix:
- Verify your token is valid at the Auth Tokens page.
- Make sure the token is set correctly, either via
lstk loginor theLOCALSTACK_AUTH_TOKENenvironment variable. - If a stale keyring token is interfering, run
lstk logoutfirst and then setLOCALSTACK_AUTH_TOKEN.
Image pull failed
Section titled “Image pull failed”If lstk cannot pull the Docker image, check your network connection and Docker configuration.
On corporate networks, you may need to configure Docker’s proxy settings, see How do I configure LocalStack to use my corporate HTTP and HTTPS proxy?.
Unknown environment profile
Section titled “Unknown environment profile”If your container config references an env profile that doesn’t exist, lstk returns:
environment "myprofile" referenced in container config not foundFix: Make sure the profile name in the env list matches an [env.<name>] section in your config.toml:
[[containers]]type = "aws"env = ["myprofile"] # must match the section name below
[env.myprofile]DEBUG = "1"Getting help
Section titled “Getting help”If the steps above don’t resolve your issue, see Get Help for the available support channels, including the support email and in-app chat.