Skip to content
Get Started for Free

lstk CLI

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.

Terminal window
brew install localstack/tap/lstk

Homebrew also installs shell completions for bash, zsh, and fish automatically.

Verify the installation:

Terminal window
lstk --version

lstk can update itself. It detects how it was originally installed (Homebrew, npm, or binary) and uses the matching update method:

Terminal window
# Check for updates without installing
lstk update --check
# Update to the latest version
lstk update

See the update command for details, including the start-time update notification.

Terminal window
lstk

Running 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:

Terminal window
LOCALSTACK_AUTH_TOKEN=<your-ci-auth-token> lstk --non-interactive

CI environments require a CI Auth Token; a personal Developer Auth Token cannot be used there.

lstk resolves your auth token in the following order:

  1. System keyring: a token stored by a previous lstk login.
  2. LOCALSTACK_AUTH_TOKEN environment variable: used only when the keyring has no token.
  3. Browser login: triggered automatically in interactive mode when neither of the above provides a token.
Terminal window
lstk login

Opens 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.

Terminal window
lstk logout

Removes 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.

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:

Terminal window
export LSTK_KEYRING=file

lstk uses a TOML configuration file, created automatically on first run.

lstk uses the first config.toml it finds in this order:

  1. ./.lstk/config.toml: project-local config in the current directory.
  2. $HOME/.config/lstk/config.toml: user config (created here if $HOME/.config/ exists).
  3. OS default:
    • macOS: $HOME/Library/Application Support/lstk/config.toml
    • Windows: %AppData%\lstk\config.toml
    • Linux: $XDG_CONFIG_HOME/lstk/config.toml or $HOME/.config/lstk/config.toml

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:

Terminal window
lstk config path

To use a specific config file:

Terminal window
lstk --config /path/to/config.toml start

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)
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).

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.

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/localstack defines the persistence directory — the same one lstk volume path and lstk volume clear act on. Precedence: a volumes entry targeting /var/lib/localstack → the legacy volume field → the default OS cache directory.
  • volume and volumes overlap only for the persistence mount. The legacy volume value is used verbatim (no path resolution); volumes sources are resolved. Setting the persistence directory via both volume and a volumes entry with different sources is a validation error.
  • The persistence directory is created automatically if missing; other volumes sources are expected to already exist (they are typically files, such as init hooks) and lstk errors if one is missing.

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:

.lstk/config.toml
[[containers]]
type = "snowflake"
port = "4566"

An AWS project might instead pin a specific image tag and enable a debug profile:

.lstk/config.toml
[[containers]]
type = "aws"
tag = "2026.4"
port = "4566"
env = ["dev"]
[env.dev]
DEBUG = "1"
PERSISTENCE = "1"

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).

Terminal window
lstk start
lstk start --persist
lstk 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.

Terminal window
# Start with persistent state
lstk start --persist

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.

Terminal window
lstk stop
lstk stop --non-interactive

stop 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.

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.

Terminal window
lstk restart
lstk 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.

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.

Terminal window
lstk status
lstk --non-interactive status

For 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 configured port was 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 -h

For 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 Account
S3 my-bucket us-east-1 000000000000
SQS my-queue us-east-1 000000000000

In 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.

Terminal window
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:

Terminal window
# Print current filtered logs and exit
lstk logs
# Stream filtered logs in real-time
lstk logs --follow
# Stream all logs without filtering
lstk logs --follow --verbose

Run 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.

Terminal window
lstk aws s3 ls
lstk aws sqs list-queues
lstk aws s3 mb s3://my-bucket

It is equivalent to running:

Terminal window
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).

lstk aws injects credentials in one of two ways:

  • Profile mode: if a complete localstack profile exists in both ~/.aws/config and ~/.aws/credentials, lstk appends --profile localstack and lets aws read the region, credentials, and endpoint from that profile.
  • Profile-less mode: if the profile is not present, lstk runs aws with AWS_ACCESS_KEY_ID=test, AWS_SECRET_ACCESS_KEY=test, and AWS_DEFAULT_REGION=us-east-1 injected 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.

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.

Terminal window
lstk az group list
lstk az storage account list

Run 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.

Terminal window
lstk az start-interception # global 'az' now targets LocalStack
lstk az stop-interception # switch back to real Azure
  • start-interception registers and activates the LocalStack cloud in ~/.azure and disables instance discovery, so existing az scripts run unmodified against LocalStack. It is independent of lstk setup azure.
  • stop-interception switches the active cloud back to AzureCloud (override with --cloud <name>) and re-enables instance discovery — but only if LocalStack is 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.

Proxy Terraform commands to LocalStack, injecting LocalStack endpoints as AWS provider overrides so your existing configuration runs unchanged. Aliased as lstk tf.

Terminal window
lstk terraform init
lstk terraform --region us-west-2 plan
lstk tf apply

lstk-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.

Terminal window
lstk cdk bootstrap
lstk cdk --region us-west-2 deploy
lstk cdk synth

CDK 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).

Terminal window
lstk sam build
lstk sam --region us-west-2 deploy
lstk sam validate

lstk-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.

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.

Save a snapshot of the running emulator’s state. The emulator must already be running; this command does not auto-start it.

Terminal window
# Auto-named snapshot file in the current directory
lstk snapshot save
# Save to a specific local path
lstk 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/prefix
lstk snapshot save my-pod s3://my-bucket/prefix --profile my-aws-profile

The 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.

Load a snapshot into the emulator, auto-starting it first if it is not already running.

Terminal window
# Load a local snapshot by path or name
lstk snapshot load my-baseline
lstk 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 state
lstk snapshot load pod:my-baseline --merge=overwrite

The 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:

Terminal window
lstk save pod:my-baseline
lstk load ./checkpoint

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.

Terminal window
# Snapshots you created
lstk snapshot list
# Every snapshot in your organization
lstk 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).

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.

Terminal window
lstk snapshot remove pod:my-baseline
# Skip the confirmation prompt (required in non-interactive mode)
lstk snapshot remove pod:my-baseline --force

The required REF argument must be a pod:<name> Cloud Pod reference.

Option Description
--force Skip the confirmation prompt. Required when running non-interactively.

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.

Terminal window
lstk snapshot show pod:my-baseline

The required REF argument must be a pod:<name> Cloud Pod reference.

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 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). 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, lstk runs 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.

Terminal window
lstk reset
lstk 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 mode

Manage the emulator volume: the host directory that holds persistent state such as certificates, downloaded tools, and persistence data.

Terminal window
lstk volume path
lstk volume clear [options]

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).

Terminal window
# Print the volume directory for each configured emulator
lstk volume path

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
Terminal window
# Clear all configured emulator volumes (prompts for confirmation)
lstk volume clear
# Clear only the AWS emulator volume
lstk volume clear --type aws
# Skip the confirmation prompt
lstk volume clear --force
# Clear without prompting in a non-interactive environment
lstk volume clear --type snowflake --force

In 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.

Terminal window
lstk login

lstk 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.
Terminal window
# Force file-based token storage during login
LSTK_KEYRING=file lstk login
# Use a specific config file
lstk --config ./.lstk/config.toml login

Remove stored authentication credentials.

Terminal window
lstk logout
lstk logout --non-interactive

logout 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).

Terminal window
lstk setup aws
lstk setup azure

Create or update a localstack profile in ~/.aws/config and ~/.aws/credentials so the AWS CLI and SDKs can target LocalStack.

Terminal window
lstk setup aws
lstk 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):

~/.aws/config
[profile localstack]
region = us-east-1
output = json
endpoint_url = http://localhost.localstack.cloud:4566
# ~/.aws/credentials
[localstack]
aws_access_key_id = test
aws_secret_access_key = test

Afterwards, target LocalStack by passing --profile localstack or exporting AWS_PROFILE:

Terminal window
export AWS_PROFILE=localstack
aws s3 ls

The 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.

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.

Terminal window
lstk setup azure

Requires 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.

Manage CLI configuration. config has no behavior of its own; run it with a subcommand.

Print the resolved path to the active config.toml.

Terminal window
lstk config path

This 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.

Write a LocalStack AWS CLI profile into ~/.aws/config and ~/.aws/credentials, pointing at your configured emulator.

Terminal window
lstk config profile # prefer: lstk setup aws

Requires an interactive terminal. In non-interactive mode it fails with:

config profile requires an interactive terminal

The generated profile uses the host from the LOCALSTACK_HOST environment variable (when set) and your configured containers, identical to setup aws.

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.

Terminal window
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:

Terminal window
# Check for updates without installing
lstk update --check
# Update to the latest version
lstk update
# Update with plain (non-TUI) output
lstk update --non-interactive

By install method:

  • Homebrew (binary under a Caskroom path): runs brew upgrade localstack/tap/lstk.
  • npm (binary under node_modules): runs npm 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.

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.toml so 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.

Generate shell completion scripts.

Terminal window
lstk completion [bash|zsh|fish|powershell]

See Shell completions for setup instructions.

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

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 of reset/volume clear display 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.
Terminal window
# Force plain output even in an interactive terminal
lstk --non-interactive start

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.

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.

lstk can export traces of its own command execution over OTLP/HTTP. Tracing is disabled by default. Enable it with:

Terminal window
LSTK_OTEL=1 lstk start

When 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.

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 path to find the config directory; lstk.log sits alongside config.toml.

lstk includes completion scripts for bash, zsh, fish, and powershell. If you installed via Homebrew, completions are set up automatically.

For manual setup:

Terminal window
# Load in current session
source <(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

Restart your shell after persisting completions.

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.

Terminal window
# Runs the lstk-hello executable, forwarding "world"
lstk hello world

Built-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).

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.

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.

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"

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 use

Fix: 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.

lstk requires a running Docker daemon. If Docker is not reachable, you will see an error like:

Error: runtime not healthy

Fix: 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 mode

Fix: Set the LOCALSTACK_AUTH_TOKEN environment variable before running lstk:

Terminal window
export LOCALSTACK_AUTH_TOKEN=<your-token>
lstk --non-interactive start

You can find your auth token on the Auth Tokens page.

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 login or the LOCALSTACK_AUTH_TOKEN environment variable.
  • If a stale keyring token is interfering, run lstk logout first and then set LOCALSTACK_AUTH_TOKEN.

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?.

If your container config references an env profile that doesn’t exist, lstk returns:

environment "myprofile" referenced in container config not found

Fix: 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"

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.

Was this page helpful?