Floci Local AWS Development: Cut Costs, Ship Faster
Slash AWS dev costs and accelerate feedback loops. This guide shows how to set up Floci for robust local AWS development, comparing it to Localstack.
Umair · Senior Flutter Developer
March 22, 2026 · 11 min read
Every single Lambda change uploading to AWS for testing was costing me minutes and pennies. Those pennies add up, and the slow feedback loop drove me nuts. After enough frustration, I dug in. This is how I finally got fast, free Floci local AWS development working, completely transforming my local serverless workflow. Forget the cloud for dev; this is the way.
Why Your Wallet Hates Cloud-First Dev (And Why Floci Wins)
Honestly, developing directly against AWS for every little change is a trap. You get hit with:
- Slow Feedback Loops: Deploying a Lambda, even a tiny one, takes time. Waiting for logs, checking metrics, re-deploying. It kills flow.
- Hidden Costs: Those "free tier" allowances run out. Every SQS message, every S3 PutObject, every Lambda invocation adds up. Next thing you know, your personal dev account is racking up $50-$100 a month for stuff you shouldn't be paying for.
- Internet Dependency: What happens when your internet drops? Or you're on a flight? You're completely blocked from doing
offline AWS testing. This is just bad for productivity. - Complex Debugging: Debugging remote Lambda functions is painful. Local tools are always better for breakpoints and rapid iteration.
This is where Floci shines. It's a genuine Localstack alternative free solution, specifically built to handle core serverless services locally. You get your AWS local serverless environment running on your machine, no internet needed.
Here’s why Floci is a game-changer for me:
- Zero AWS Costs: Develop all day, every day, without seeing a single charge on your bill. This alone helps
reduce AWS dev costssignificantly. - Instant Feedback: Invoke Lambdas, push SQS messages, store S3 objects locally with near-instant responses.
- True Offline Capabilities: Build and test anywhere, anytime. Plane, train, remote cabin – doesn't matter.
Floci vs. Localstack: The Real Showdown for AWS Local Serverless
Everyone knows Localstack. It's the go-to for many, and for good reason: it’s powerful, supports a ton of services, and has a mature ecosystem. But here’s the thing — Localstack has a tiered pricing model. A lot of the advanced features you really want for local dev, like Kinesis or DynamoDB Streams, are locked behind their Pro subscription. For basic S3, Lambda, SQS, DynamoDB, the free version is okay, but it can still be a heavy Docker image.
Floci, on the other hand, is built differently. It's designed to be a lightweight, truly free, open-source emulator for common serverless components. It's not trying to emulate every single AWS service in excruciating detail. Instead, it focuses on the ones you use daily for serverless apps: Lambda, SQS, S3, DynamoDB, API Gateway, SNS.
Here’s my take:
- Localstack (Free Tier): Good for basic S3/SQS/DynamoDB. Can be a bit slow to start, and the full power is behind a paywall.
- Localstack (Pro Tier): If your company is paying, and you need a very broad, highly accurate emulation of many AWS services, it’s a strong contender. But it’s not your free solution.
- Floci: This is my winner for individuals and small teams focused on
AWS local serverlessdevelopment who want toreduce AWS dev coststo zero. It's faster, lighter, and crucially, 100% free and open-source, forever. It nails the core services you need for everyday development, offering a fantasticLocalstack alternative freethat doesn't nickel and dime you. For pureoffline AWS testingof serverless patterns, Floci is hard to beat.
Is Floci as feature-rich as Localstack Pro? No, not yet. But for 90% of what I do day-to-day with serverless, it's perfect. The emphasis on speed and being completely free makes it invaluable.
Getting Down with Floci: Your Local AWS Environment Setup
Setting up Floci is straightforward, mainly involving Docker. If you're building modern cloud apps, you probably already have Docker installed. If not, get it.
First, make sure Docker is running on your machine. Then, you just need to pull the image and run it. The beauty of Floci is its simplicity.
Pull the Floci Docker Image: This command grabs the latest stable version of Floci.
docker pull umgmd/floci:latestIt's a relatively small image, so it should download quickly.
Run Floci: Now, let's fire it up. We'll map ports so our local services can talk to Floci. I usually pick a consistent port like
4566to mimic Localstack's default, just for muscle memory.docker run -d --rm \ --name floci-dev-env \ -p 4566:4566 \ -p 4510:4510 \ umgmd/floci:latest-d: Runs the container in detached mode (background).--rm: Automatically removes the container when it exits. Clean.--name floci-dev-env: Gives it a memorable name.-p 4566:4566: Maps the main Floci API port. This is where your AWS SDKs and CLI will connect.-p 4510:4510: This is often used for specific services like API Gateway endpoints in some setups. Good to include.
Once you run this, you'll have a local AWS emulator humming along. You can check its status with
docker ps.docker psYou should see
floci-dev-envlisted and running.Configure Your AWS CLI/SDK: This is the crucial part for
Floci local AWS development. You need to tell your AWS CLI and SDKs to talk to your local Floci instance instead of the real AWS cloud.For AWS CLI: You can export an environment variable or add
--endpoint-urlto every command. For quick dev, I prefer the export.# Set this in your shell config (.bashrc, .zshrc, etc.) or just run it per session export AWS_ENDPOINT_URL="http://localhost:4566" export AWS_ACCESS_KEY_ID="test" # Floci doesn't care about real credentials for local calls export AWS_SECRET_ACCESS_KEY="test" export AWS_DEFAULT_REGION="us-east-1" # Or whatever region you useNow, any
awscommand will automatically point to your local Floci instance. No more cloud billing for test commands!For AWS SDK (Node.js example): When initializing your AWS SDK clients, you explicitly tell them where to find the endpoint.
const { SQSClient, SendMessageCommand } = require("@aws-sdk/client-sqs"); const { LambdaClient, InvokeCommand } = require("@aws-sdk/client-lambda"); const { DynamoDBClient } = require("@aws-sdk/client-dynamodb"); const { S3Client } = require("@aws-sdk/client-s3"); // Common configuration for local Floci const localAwsConfig = { endpoint: "http://localhost:4566", region: "us-east-1", // Must match your default region credentials: { accessKeyId: "test", secretAccessKey: "test", }, // This is important for Floci with some services, like S3 paths forcePathStyle: true, }; const sqsClient = new SQSClient(localAwsConfig); const lambdaClient = new LambdaClient(localAwsConfig); const dynamoDbClient = new DynamoDBClient(localAwsConfig); const s3Client = new S3Client(localAwsConfig); // Now you can use these clients to interact with Floci async function sendLocalSqsMessage() { try { const queueUrl = "http://localhost:4566/000000000000/my-local-queue"; // Floci often uses dummy account ID const command = new SendMessageCommand({ QueueUrl: queueUrl, MessageBody: "Hello from local Floci!", }); const response = await sqsClient.send(command); console.log("Local SQS message sent:", response); } catch (error) { console.error("Error sending local SQS message:", error); } } // Example usage: // sendLocalSqsMessage();Remember
forcePathStyle: truefor S3; it's a common requirement for local S3 emulators to work correctly with the SDK. This is critical if you're doing any local S3 interactions.
Integrating Floci: A Serverless Example (Node.js Lambda + SQS)
Let's build a quick example where a Lambda processes messages from an SQS queue, all running locally using Floci local AWS development. This pattern is super common.
Scenario: We have an SQS queue where messages are sent. A Lambda function is configured to process these messages.
Step 1: Create a Local SQS Queue
With AWS_ENDPOINT_URL set, this is simple.
aws sqs create-queue --queue-name my-local-queue
You should get a response like:
{
"QueueUrl": "http://localhost:4566/000000000000/my-local-queue"
}
Keep this QueueUrl handy. The 000000000000 is Floci's default dummy account ID.
Step 2: Write Your Local Lambda Function
Create a file named my-local-lambda.js:
// my-local-lambda.js
const { SQSClient, SendMessageCommand } = require("@aws-sdk/client-sqs");
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3");
// IMPORTANT: Ensure your localAwsConfig is aligned with your Floci setup
const localAwsConfig = {
endpoint: "http://localhost:4566",
region: "us-east-1",
credentials: {
accessKeyId: "test",
secretAccessKey: "test",
},
forcePathStyle: true, // Crucial for local S3
};
const sqsClient = new SQSClient(localAwsConfig);
const s3Client = new S3Client(localAwsConfig);
exports.handler = async (event) => {
console.log("Received event:", JSON.stringify(event, null, 2));
for (const record of event.Records) {
const messageBody = record.body;
console.log("Processing SQS message:", messageBody);
try {
// Simulate some processing, maybe saving to S3
const bucketName = "my-local-bucket";
const objectKey = `processed-messages/${Date.now()}.json`;
const s3Command = new PutObjectCommand({
Bucket: bucketName,
Key: objectKey,
Body: JSON.stringify({ originalMessage: messageBody, processedAt: new Date().toISOString() }),
ContentType: "application/json",
});
await s3Client.send(s3Command);
console.log(`Saved message to S3: s3://${bucketName}/${objectKey}`);
// Optionally, send a follow-up message to another SQS queue
// const anotherQueueUrl = "http://localhost:4566/000000000000/another-local-queue";
// const followUpCommand = new SendMessageCommand({
// QueueUrl: anotherQueueUrl,
// MessageBody: `Processed: ${messageBody}`,
// });
// await sqsClient.send(followUpCommand);
// console.log("Sent follow-up SQS message.");
} catch (error) {
console.error("Error processing message or interacting with local S3/SQS:", error);
// Important for SQS: If you throw an error, SQS will re-deliver the message
throw error;
}
}
return {
statusCode: 200,
body: JSON.stringify('Messages processed successfully'),
};
};
Make sure you have @aws-sdk/client-sqs and @aws-sdk/client-s3 installed (npm i @aws-sdk/client-sqs @aws-sdk/client-s3).
Step 3: Create a Local S3 Bucket (for the Lambda to use)
aws s3 mb s3://my-local-bucket
Step 4: Create and Deploy the Local Lambda Function to Floci This requires zipping your Lambda code.
# Create a zip file of your Lambda code
zip my-local-lambda.zip my-local-lambda.js
# Create the Lambda function in Floci
aws lambda create-function \
--function-name my-local-processor \
--runtime nodejs18.x \
--handler my-local-lambda.handler \
--zip-file fileb://my-local-lambda.zip \
--role arn:aws:iam::000000000000:role/lambda-role # Floci doesn't validate IAM, a dummy ARN is fine
Step 5: Invoke the Lambda Function (simulating an SQS event)
While Floci can configure event sources, for rapid offline AWS testing, it's often faster to manually craft an event.
# Create a sample SQS event payload (save as event.json)
cat << EOF > event.json
{
"Records": [
{
"messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
"receiptHandle": "MessageReceiptHandle",
"body": "{\"data\":\"Hello Floci! This is a test message.\"}",
"attributes": {
"ApproximateReceiveCount": "1",
"SentTimestamp": "1523232000000",
"SenderId": "AIDEXAMPLE",
"ApproximateFirstReceiveTimestamp": "1523232000001"
},
"messageAttributes": {},
"md5OfBody": "098f6bcd4621d373cade4e832627b4f6",
"eventSource": "aws:sqs",
"eventSourceARN": "arn:aws:sqs:us-east-1:000000000000:my-local-queue",
"awsRegion": "us-east-1"
}
]
}
EOF
# Invoke the local Lambda
aws lambda invoke \
--function-name my-local-processor \
--payload file://event.json \
output.json
Check output.json for the Lambda's response, and importantly, check your Docker logs for floci-dev-env to see the console.log output from your Lambda.
docker logs floci-dev-env
You should see your Lambda's console.log messages indicating it processed the SQS message and saved to S3. To verify the S3 object:
aws s3 ls s3://my-local-bucket/processed-messages/
This whole workflow lets you rapidly iterate on your Lambda code and AWS local serverless interactions without hitting the cloud even once. It's a massive win for feedback speed and reducing reduce AWS dev costs.
What I Got Wrong First
I've wasted hours on silly things that are obvious in hindsight. Here are some of the common pitfalls I hit with local AWS emulation, especially with a tool like Floci:
Endpoint URL Mismatch:
- Error:
Could not connect to the endpoint URL: "http://localhost:4566/"orUnknown endpoint: http://localhost:4566. - My Mistake: Forgetting that my Docker container wasn't actually running, or the port mapping was wrong. Sometimes, I'd forget to set
AWS_ENDPOINT_URLfor the CLI, or hardcode the wrong port in my SDK. - The Fix: Always check
docker psfirst. Make sure your Floci container (floci-dev-envin our case) is up and running. Double-check your-pflag indocker run. For SDKs, ensure theendpointURL inlocalAwsConfigishttp://localhost:4566(or whatever port you chose). Remember,localhostrefers to your host machine'slocalhost, which is exposed to the Docker container via port mapping.
- Error:
IAM Credentials & Permissions:
- Error:
The request signature we calculated does not match the signature you provided.orAccessDeniedException. - My Mistake: Overthinking local IAM. I'd try to pass real AWS credentials or create complex local IAM setups.
- The Fix: Floci (and most local emulators) generally doesn't care about real AWS credentials for local calls. For the AWS CLI and SDKs, providing any non-empty
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY(like "test"/"test" as I showed) is usually sufficient for it to attempt signing, which Floci then ignores. For Lambdacreate-function, theroleARN can be a dummy value; Floci doesn't validate it. The key insight here is that you're operating in a mock environment, so security credentials aren't enforced the same way.
- Error:
S3 Path Style vs. Virtual Host Style:
- Error: S3 operations fail, sometimes with obscure DNS errors or bucket not found.
- My Mistake: Not setting
forcePathStyle: truein the AWS SDK for S3 operations. AWS by default tries to use virtual host addressing (e.g.,my-bucket.s3.us-east-1.amazonaws.com), but local emulators often expect path-style (e.g.,localhost:4566/my-bucket). - The Fix: Always add
forcePathStyle: trueto yourS3Clientconfiguration when working with Floci. This ensures the SDK formats requests in a way local emulators understand.
"My Lambda logs aren't showing up!"
- My Mistake: Looking for Lambda logs in CloudWatch (which doesn't exist locally) or expecting them to just print to my terminal.
- The Fix: Lambda logs go to the Floci Docker container's standard output. Use
docker logs floci-dev-envto see yourconsole.logstatements from your local Lambda invocations. This is how you debug your local functions.
Anyway, these little gotchas cost time. Knowing them upfront will save you pain.
Beyond the Basics: Quick Wins & Gotchas
- Cleaning Your Local State: Floci, by default, is ephemeral if you use
--rm. If you want to explicitly clear all local data (SQS messages, S3 objects, DynamoDB tables), just stop and remove the container:
Then restart it with thedocker stop floci-dev-env # (if not using --rm, then also) docker rm floci-dev-envdocker runcommand. It's a fresh slate every time, which is great for repeatable tests. - Persistent Data (if you need it): If you do need data to persist across container restarts (e.g., for long-running dev tasks where you don't want to re-seed DynamoDB), you can use Docker volumes.
I honestly don't use this much for Floci because I prefer a clean state for mostdocker run -d --rm \ --name floci-dev-env \ -p 4566:4566 \ -p 4510:4510 \ -v floci-data:/var/lib/floci # This creates a named volume umgmd/floci:latestoffline AWS testing, but it's there if you need it. - Supported Services: Floci focuses on common serverless services: Lambda, SQS, SNS, S3, DynamoDB, API Gateway, CloudWatch Events (for scheduling). Don't expect it to emulate things like ECS, RDS, Glue, or Kinesis Streams yet. For those, you'd likely still need cloud or a more comprehensive (and potentially paid) tool. This is a design choice that keeps Floci lean and fast.
FAQs
Does Floci support all AWS services?
No. Floci focuses on core serverless services like Lambda, SQS, SNS, S3, DynamoDB, and API Gateway. It's optimized for lightweight, fast emulation of these common services, not every single AWS offering.
How do I make my existing AWS SDK code work with Floci?
You need to explicitly configure your AWS SDK clients (e.g., SQSClient, S3Client) with endpoint: "http://localhost:4566", region: "us-east-1", and dummy credentials. For S3, also add forcePathStyle: true.
Is Floci suitable for CI/CD pipelines?
Yes, absolutely. Because it's Docker-based and truly open-source, you can spin up Floci containers as part of your CI/CD pipeline to run integration tests against a local AWS environment, saving costs and speeding up test execution.
Look, this isn't rocket science, but getting your local Floci local AWS development environment humming smoothly makes a huge difference. For offline AWS testing and serious reduce AWS dev costs on serverless applications, Floci is an underrated gem. It's fast, free, and gets the job done for 90% of what you need day-to-day. Stop paying AWS for your dev cycles and get your feedback loops tight. Go spin up Floci; your wallet and your sanity will thank you.
Need a Flutter developer?
I build production apps from scratch — iOS, Android, AI features, payments. Let's talk.
Book Free Call →Related Posts
Local LLM Video Captioning: Private, Powerful, Open-Source
Discover how to build robust, privacy-focused local LLM video captioning tools using open-source models without cloud APIs.
AI Assisted Coding Benefits: A Pro Developer's Deep Dive
Explore the real AI assisted coding benefits for professional developers. Dive into tools, productivity gains, and strategies to maximize AI's potential.