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 or Cloud Pods — reset running state, run AWS CLI commands against the emulator, and manage the on-disk volume.
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 = "" # Full image override (e.g. an internal mirror or offline image)# volume = "" # Host directory for persistent state (default: OS cache dir)# volumes = [] # Docker-style "host:container[:ro]" bind mounts (see Volumes)# env = [] # Named environment profiles to apply (see [env.*] sections below)# snapshot = "" # Snapshot REF to auto-load after start (AWS only)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 | (default) | Full image reference that overrides the default Docker Hub image, e.g. an internal-registry mirror or a locally loaded offline image. If it already carries a tag, tag is ignored; otherwise tag (or latest) is appended. |
volume |
string | (OS cache) | Host directory for persistent emulator state. Defaults to <os-cache>/lstk/volume/<container-name>. See also volumes. |
volumes |
string[] | [] |
Docker-style "host:container[:ro]" bind mounts (e.g. init hooks). May also carry the persistence mount (target /var/lib/localstack). See Volume mounts. |
env |
string[] | [] |
List of named environment profiles to inject into the container (see below). |
snapshot |
string | "" |
Snapshot REF (e.g. pod:my-baseline or a local path) to auto-load after the emulator starts. AWS emulator only. See Auto-loading a snapshot on start. |
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, aws, snapshot, reset, setup aws) require an aws emulator to be configured.
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.
Custom container image
Section titled “Custom container image”By default the emulator image is pulled from Docker Hub (localstack/localstack-pro, localstack/snowflake, or localstack/localstack-azure depending on type).
Set image on a container block to override it — for example, to pull from an internal-registry mirror or to run a locally loaded image in an air-gapped environment:
[[containers]]type = "aws"image = "registry.internal.example.com/localstack/localstack-pro"tag = "2026.4"If image already carries a tag (e.g. ...:2026.4), the separate tag field is ignored; otherwise tag (or latest) is appended.
See Offline and enterprise environments for how lstk falls back to a locally present image when a pull fails.
Volume mounts
Section titled “Volume mounts”Beyond the single persistence directory set by volume, a container block can declare arbitrary Docker-style bind mounts with volumes.
Each entry is a "host:container[:ro]" spec — useful, for example, for mounting Snowflake init hooks into /etc/localstack/init/{boot,start,ready,shutdown}.d:
[[containers]]type = "snowflake"port = "4566"volumes = [ "./init:/etc/localstack/init/ready.d:ro", "./data:/var/lib/localstack",]- A
volumesentry whose container target is/var/lib/localstacksets the persistence directory (the same mountvolumeconfigures); this is whatlstk volume pathandlstk volume clearresolve. - Relative host sources and a leading
~/are resolved against the config file’s directory. This differs from the legacyvolumefield, whose value is passed to Docker verbatim. - Setting the persistence directory through both
volumeand avolumesentry with a different source is a validation error.
volume and volumes overlap only for the persistence mount: volume can only set the persistence directory, while volumes is a superset that can also express init hooks and other mounts.
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> |
Auto-load this snapshot after the emulator starts, overriding the configured snapshot for one run (AWS only) |
--no-snapshot |
Skip auto-loading the configured snapshot for this run |
--non-interactive |
Disable the interactive TUI and use plain output |
lstk start forwards host environment variables prefixed with LOCALSTACK_ to the emulator (the host LOCALSTACK_AUTH_TOKEN is dropped so it cannot override the token lstk resolved). 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”For the AWS emulator, you can have lstk load a snapshot automatically every time it starts the emulator.
Set the snapshot field on the container block to any load REF (a pod:<name> Cloud Pod or a local path):
[[containers]]type = "aws"port = "4566"snapshot = "pod:my-baseline"The snapshot is loaded only when the emulator is freshly started this run; if it is already running, the auto-load is skipped.
Override it for a single run with --snapshot REF, or skip it entirely with --no-snapshot:
# Start and load a different snapshot for this run onlylstk start --snapshot pod:other-baseline
# Start without loading the configured snapshotlstk start --no-snapshotThe snapshot field is only read on start; snapshot save never writes it back into your config.
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 runs az with an isolated AZURE_CONFIG_DIR in which a custom Azure cloud is registered against LocalStack’s endpoints, so your global ~/.azure configuration is left untouched and plain az keeps talking to real Azure.
Run lstk setup azure once before using this mode.
Everything after lstk az is forwarded verbatim to the host az binary, and its exit code and output are passed through unchanged.
lstk az group listlstk az storage account listThe Azure CLI has no --endpoint-url/--profile equivalent, so the isolation relies entirely on the dedicated config directory prepared by setup azure.
Global interception (optional)
Section titled “Global interception (optional)”If a script must invoke plain az (not lstk az), you can redirect your global ~/.azure to LocalStack instead:
# Point global 'az' at the LocalStack Azure emulatorlstk az start-interception
# Switch back to real Azurelstk az stop-interceptionstart-interception registers and activates the LocalStack cloud in your global Azure configuration so every az invocation targets LocalStack until you stop it.
stop-interception switches the active cloud back to AzureCloud (override with --cloud <name>) and re-enables instance discovery, but only when LocalStack is still the active cloud, to avoid clobbering an unrelated selection.
terraform
Section titled “terraform”Run Terraform against LocalStack, using LocalStack endpoints as AWS provider overrides.
lstk terraform (alias lstk tf) generates a provider-override file and forwards your arguments to the real terraform binary.
lstk terraform initlstk terraform --region us-west-2 planlstk tf applylstk-specific flags must appear before the Terraform action:
| Option | Default | Description |
|---|---|---|
--region <region> |
us-east-1 |
Deployment region. |
--account <id> |
test |
Target AWS account id (12 digits). |
Relevant environment variables: AWS_ENDPOINT_URL (override the auto-resolved endpoint), LSTK_TF_CMD (binary to invoke, e.g. tofu; default terraform), LSTK_TF_OVERRIDE_FILE_NAME (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), and AWS_ACCESS_KEY_ID (fallback for --account).
Run the AWS CDK against LocalStack.
Requires the AWS CDK CLI version 2.177.0 or newer on your PATH.
lstk cdk bootstraplstk cdk --region us-west-2 deploylstk cdk synthThe only lstk-specific flag (before the CDK action) is --region <region> (default us-east-1); CDK always targets the default LocalStack account 000000000000, so there is no --account flag.
Relevant environment variables: AWS_ENDPOINT_URL, AWS_ENDPOINT_URL_S3, LSTK_CDK_CMD (default cdk), and AWS_REGION.
Run the AWS SAM CLI against LocalStack.
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 (before the SAM action): --region <region> (default us-east-1) and --account <id> (12 digits, default 000000000000).
Relevant environment variables: AWS_ENDPOINT_URL, AWS_ENDPOINT_URL_S3, LSTK_SAM_CMD (default sam), AWS_REGION (fallback for --region), and AWS_ACCESS_KEY_ID (fallback for --account).
snapshot
Section titled “snapshot”Manage emulator snapshots.
A snapshot captures the running emulator’s state, either as a local file on disk, as a Cloud Pod on the LocalStack platform, or 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 is auto-generated if omitted)lstk snapshot save my-pod s3://my-bucket/prefixThe optional [destination] argument takes one of these forms:
| Destination | Description |
|---|---|
| (omitted) | Auto-generates a timestamped snapshot file in the current directory (./snapshot-<timestamp>-<hex>.snapshot). |
| local path | Writes a snapshot archive to that path. The .snapshot extension is forced. |
pod:<name> |
Saves a Cloud Pod to the LocalStack platform. Requires authentication. |
<pod-name> s3://bucket/prefix |
Saves to your own S3 bucket. The pod name is a separate positional (auto-generated when omitted). See S3 remotes. |
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 (used only for s3:// destinations). Defaults to AWS_* env vars, then AWS_PROFILE. |
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 is required)lstk snapshot load my-pod s3://my-bucket/prefix
# 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 or a pod:<name> Cloud Pod.
To load from S3, pass the pod name followed by an s3://bucket/prefix location (see S3 remotes).
| 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 (used only for s3:// sources). Defaults to AWS_* env vars, then AWS_PROFILE. |
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/prefixPassing an s3://bucket/prefix location lists snapshots stored in your own S3 bucket instead of the platform (see S3 remotes). Unlike the platform listing, this queries the emulator, so it requires a running emulator.
| Option | Description |
|---|---|
--all |
List all snapshots in your organization, not just your own. |
--profile <name> |
AWS profile to read S3 credentials from (used only with an s3:// location). Defaults to AWS_* env vars, then AWS_PROFILE. |
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: its name, created date, size, LocalStack version, message, the services it contains, and per-service resource counts (resource counts render only when the platform has them for that snapshot). This subcommand is 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 a snapshot stored in your own S3 bucket by passing an s3://bucket/prefix location.
The pod name (the snapshot’s identity within the bucket) is a positional separate from the s3:// location — required for load, auto-generated for save when omitted, and unused for list.
lstk snapshot save my-pod s3://my-bucket/prefixlstk snapshot load my-pod s3://my-bucket/prefixlstk snapshot list s3://my-bucket/prefixCredentials follow AWS CLI precedence: --profile <name> wins, otherwise the static AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY (plus optional AWS_SESSION_TOKEN) environment variables, otherwise the profile named by AWS_PROFILE.
Only static credentials are supported (no SSO, assume-role, or credential_process), and credentials must never be embedded in the URL.
lstk runs a pre-flight check that the target bucket exists and errors out rather than letting the emulator auto-create a bucket on a typo.
Because the transfer is performed by the emulator (not the CLI), S3 remotes require a running emulator, and list s3://… in particular queries the emulator rather than the platform API.
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, setup aws and setup 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 |
Overwrite an existing localstack profile whose values differ, and skip the confirmation prompt. |
On an interactive terminal it prompts (Y/n) before making changes.
In non-interactive mode (piped output, CI, or --non-interactive) it writes the profile with defaults without prompting and exits 0; a failed write or check returns a non-zero exit code so automation notices.
Overwriting an existing localstack profile whose values differ requires --force (which also skips the interactive prompt); creating a fresh profile, completing a partial one, or leaving an already-correct profile in place never needs it.
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.
setup azure
Section titled “setup azure”Prepare an isolated Azure CLI configuration directory that routes lstk az commands to the LocalStack Azure emulator.
Your global ~/.azure configuration is left untouched.
lstk setup azure# alias:lstk setup azsetup azure registers a custom Azure cloud (LocalStack) whose endpoints point at the LocalStack Azure emulator, activates it, disables Azure CLI instance discovery and telemetry, and performs a one-time dummy service-principal login — all inside a dedicated config directory under the lstk config dir (via AZURE_CONFIG_DIR).
It requires the az CLI to be installed and a running LocalStack Azure emulator.
To instead redirect your global az (so existing scripts run unmodified against LocalStack), see lstk az start-interception.
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.
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 |
--json |
Output in JSON format (only supported by some commands, e.g. the tool proxies and extensions) |
--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 one run) |
--no-snapshot |
Skip auto-loading the configured snapshot (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. |
LOCALSTACK_CLIENT_NAME |
lstk |
Identifies the client that started the emulator. |
LOCALSTACK_CLIENT_VERSION |
(the lstk version) |
Version of the client that started the emulator. |
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.
Offline and enterprise environments
Section titled “Offline and enterprise environments”There is no --offline flag. Instead, lstk degrades gracefully when common enterprise blockers (Docker Hub unreachable, a proxy/TLS interceptor, or an unreachable license server) prevent an internet request:
- Image pull: if the image pull fails but the image is already present locally,
lstkwarns and uses the local image instead of failing. In interactive mode you can also press Esc to abort an in-progress pull and fall back to the local image. - License pre-flight: when the pinned image is already present locally,
lstkskips its pre-flight license check so a fully offline start is not blocked; the container validates its own bundled license at startup. When a check does run, a definitive server rejection (e.g. HTTP 403/400) is still fatal, but a transport-level failure (offline, proxy, or certificate error) is treated as non-fatal and the container validates its own license instead. - Telemetry and update checks are best-effort and fail silently when offline.
Pair this behavior with a custom image that points at an internal-registry mirror or a locally loaded image to run lstk in an air-gapped environment.
Extensions
Section titled “Extensions”lstk supports Git-style extensions: when lstk <name> is not a built-in command or alias, lstk looks for an executable named lstk-<name> and runs it, forwarding all arguments after <name> verbatim, passing through stdin/stdout/stderr, and propagating its exit code.
Built-in commands always take precedence — extension dispatch happens only for otherwise-unknown commands.
Resolution order is built-ins → the directory containing the lstk executable (bundled extensions) → your PATH.
lstk passes runtime context to the extension through two environment variables: LSTK_EXT_API_VERSION (an integer the extension checks before parsing) and LSTK_EXT_CONTEXT (a JSON object with the config directory, auth token, interactive/JSON flags, and the running emulators).
There is no manifest — any resolvable lstk-<name> executable is the <name> extension.
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.
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.