Skip to content
Get Started for Free

Local Development

In this quickstart you’ll start LocalStack and deploy a simple serverless API including a Lambda function backed by DynamoDB, entirely on your local machine. No AWS account needed.

By the end you will have:

  • LocalStack running locally in Docker
  • A Lambda function deployed and invokable via a public URL
  • A DynamoDB table storing data written by the Lambda
  • A local environment that behaves like real AWS

Choose your preferred deployment style below: AWS CLI or Terraform.

The fastest way to get LocalStack running locally is with lstk, a lightweight CLI that handles authentication and image setup automatically.

Install lstk:

Terminal window
brew install localstack/tap/lstk # macOS / Linux with Homebrew
Terminal window
npm install -g @localstack/lstk # or via npm

Then start LocalStack:

Terminal window
lstk

On first run, lstk opens a browser window to authenticate. It also pulls the LocalStack image and starts the container automatically.

When the container is ready, you’ll see log lines like:

Terminal window
✔︎ LocalStack ready (containerId: 400b3e61f3c6)
Endpoint: localhost.localstack.cloud:4566
Web app: https://app.localstack.cloud
> Tip: View deployed resources: lstk status

Now deploy a Lambda function and a DynamoDB table. For this tutorial, you can choose between creating resources using the AWS CLI via our awslocal wrapper or Terraform via our tflocal wrapper.

  1. Install the awslocal wrapper if you haven’t already:

    Terminal window
    pip install awscli-local
  2. Create the Lambda function

    The below code creates a Lambda function using Python and zips the code to be ready for deployment.

    Terminal window
    mkdir -p /tmp/localstack-demo
    cat > /tmp/localstack-demo/handler.py << 'EOF'
    import json, boto3, os, uuid
    def handler(event, context):
    table = boto3.resource('dynamodb').Table(os.environ['TABLE_NAME'])
    method = event.get('requestContext', {}).get('http', {}).get('method', 'GET')
    if method == 'POST':
    item = {'id': str(uuid.uuid4()), **json.loads(event.get('body', '{}'))}
    table.put_item(Item=item)
    return {'statusCode': 200, 'body': json.dumps(item)}
    result = table.scan()
    return {'statusCode': 200, 'body': json.dumps(result['Items'])}
    EOF
    cd /tmp/localstack-demo && zip handler.zip handler.py
  3. Create the DynamoDB table

    Terminal window
    awslocal dynamodb create-table \
    --table-name Messages \
    --attribute-definitions AttributeName=id,AttributeType=S \
    --key-schema AttributeName=id,KeyType=HASH \
    --billing-mode PAY_PER_REQUEST
  4. Deploy the Lambda

    Terminal window
    awslocal lambda create-function \
    --function-name messages-api \
    --runtime python3.12 \
    --handler handler.handler \
    --zip-file fileb:///tmp/localstack-demo/handler.zip \
    --role arn:aws:iam::000000000000:role/lambda-role \
    --environment Variables={TABLE_NAME=Messages}
    awslocal lambda wait function-active --function-name messages-api
  5. Create a public function URL

    Terminal window
    awslocal lambda create-function-url-config \
    --function-name messages-api \
    --auth-type NONE
  6. Retrieve the URL

    Terminal window
    LAMBDA_URL=$(awslocal lambda list-function-url-configs \
    --function-name messages-api \
    --query 'FunctionUrlConfigs[0].FunctionUrl' \
    --output text)
    echo $LAMBDA_URL

Store a message:

Terminal window
curl -X POST "$LAMBDA_URL" \
-H "Content-Type: application/json" \
-d '{"message": "Hello, LocalStack!"}'

You should get back a response like:

{ "id": "a1b2c3d4-...", "message": "Hello, LocalStack!" }

List all messages:

Terminal window
curl "$LAMBDA_URL"

That’s the win. You just invoked a real Lambda function that wrote to a real DynamoDB table — all running locally, with no AWS account and no cloud costs.

You can browse the resources you just deployed in the LocalStack Web Application. Navigate to your Default Instance and click through to Lambda or DynamoDB to see your running infrastructure.

First, stop LocalStack to tear down all local resources:

bash lstk stop

LocalStack is ephemeral by default — stopping it removes all provisioned resources. To persist state across restarts, see Persistence or Cloud Pods.

Now that you’re done, you can remove the tutorial files from your machine (the Lambda source, zip, and, if you used Terraform, main.tf and state under the same folder):

Terminal window
rm -rf /tmp/localstack-demo
  • Tutorials — Deeper dives into specific AWS services and application stacks
  • Supported Services — Full list of emulated AWS services
  • CI/CD Setup — Run LocalStack in GitHub Actions and other pipelines
  • AI & Agent Workflows — Use LocalStack with AI coding tools and agents
  • Toolingawslocal, tflocal, LocalStack Desktop, and more
Was this page helpful?