AWS Builder Center

🧠 I Let Kiro Build an Entire AWS Application — Here’s What Happened

Building an AI fridge recipe generator with AWS Amplify Gen 2, Amazon Bedrock and Kiro.

🪝 Intro — The Problem

You open your fridge.
It’s full.
And somehow… there’s nothing to eat.
You stare at a random collection of ingredients:
  • Half a broccoli
  • Some chicken
  • A mystery container that’s been sitting there for days
A few minutes later, you’re still standing there with no idea what to cook.
So you give up.
👉 You order food.
👉 Or worse — you let perfectly good ingredients go to waste.
I kept running into this exact problem.
Not because I didn’t have food, but because I couldn’t quickly turn what I had into an actual meal.
That got me thinking:
What if I could simply take a photo of my fridge and let AI figure out what I could cook using the ingredients I already have?
That question became the starting point for this project.

💡 The Idea

I wanted to keep the idea as simple as possible.
Take a photo of your fridge.
Get a recipe that uses the ingredients you already have and minimizes any additional groceries.
That’s it.
No complicated workflows.
No endless configuration.
Just something genuinely useful.

🎯 MVP Scope (Intentionally Small)

For the first version, I focused on the absolute minimum needed to validate the idea:
  • 📸 Upload a photo
  • 🧠 AI identifies likely ingredients
  • 🍝 AI generates a recipe
  • 🛒 Suggests only a few additional ingredients when necessary
  • 🔐 Basic authentication using Amazon Cognito
If those five things worked, the MVP would be a success.

🚫 What I Deliberately Didn’t Build

It’s tempting to keep adding features.
That’s also how side projects end up unfinished.
To avoid that trap, I deliberately cut the scope and focused on solving a single problem well.
Not included in version one:
  • ❌ Calorie tracking
  • ❌ Perfect food detection (good enough beats perfect)
  • ❌ Fancy UI
  • ❌ Social features
There were plenty of ideas for future versions, but they could wait.
The goal was to get something working first.

⚡ Why This Matters

I wasn’t trying to build the perfect app.
I was trying to build something that:
  • Works end-to-end
  • Solves a real problem
  • Can be built quickly
Because in my experience:
A simple app that works is infinitely more valuable than a complex app that never ships.

🏗️ Architecture — Serverless First

For the architecture, I wanted to keep everything serverless.
No servers to manage.
No containers to patch.
No database clusters to maintain.
Just managed AWS services that scale when needed.
This wasn’t a production-scale application. It was an MVP.
I wanted to spend my time building features, not managing infrastructure.

🧱 The Stack

I decided to use AWS services wherever possible:
  • Frontend: Next.js hosted with AWS Amplify
  • Fullstack Framework: AWS Amplify Gen 2
  • Authentication: Amazon Cognito
  • Storage: Amazon S3
  • Backend: AWS Lambda
  • Database: Amazon DynamoDB
  • AI: Amazon Bedrock
This gave me a fully serverless architecture with very little operational overhead.

🧭 High-Level Architecture

1
2
3
4
5
6
7
8
9
Next.js App
↓
AWS Amplify Gen 2
├── Auth → Amazon Cognito
├── Storage → Amazon S3
├── Data → Amazon DynamoDB
└── Function → AWS Lambda
↓
Amazon Bedrock
Amplify Gen 2 acts as the glue between all the AWS services.
Instead of manually configuring dozens of resources, I could define the infrastructure directly in TypeScript and let Amplify handle the heavy lifting.

🔄 Application Flow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
User
↓
Login with Cognito
↓
Upload fridge photo
↓
Store image in S3
↓
Call Lambda function
↓
Analyze image and generate recipe with Bedrock
↓
Store result in DynamoDB
↓
Show recipe in the Next.js UI
At a high level, the workflow is surprisingly simple.
The user uploads a photo.
The application sends that photo to an AWS Lambda function.
The Lambda function asks Bedrock two questions:
  1. What ingredients can you identify in this image?
  2. What recipe can I make with those ingredients?
The generated recipe is then stored in DynamoDB and displayed in the application.

🧠 In Simple Terms

The user logs in.
Uploads a photo of their fridge.
The image is stored in Amazon S3.
AWS Lambda sends the image to Amazon Bedrock.
Bedrock identifies likely ingredients and generates a recipe.
The result is stored in DynamoDB.
The recipe is displayed in the application.
That’s the entire MVP.

⚡ Why This Architecture

The goal was never to build the most sophisticated architecture.
The goal was to build something that was:
  • Simple
  • Scalable
  • Cheap to run
  • Fast to develop
By using Amplify Gen 2 and a serverless architecture, I could focus on validating the idea rather than managing infrastructure.
For an MVP, that’s exactly what I wanted.

🤖 Why I Used Kiro (and How I Kept It Useful)

I wanted to use AI to speed up development.
But I didn’t want to blindly generate thousands of lines of code and hope for the best.
Instead, I treated Kiro as an engineering assistant rather than a code generator.
The goal wasn’t to replace the development process.
The goal was to accelerate it.

⚙️ My Strategy

I started by using Kiro to help structure the project:
  • Define the MVP scope
  • Generate requirements
  • Create a technical design
  • Build an implementation plan
In other words, I used Kiro to answer questions like:
What should I build?
and
In what order should I build it?
before asking:
Can you generate the code?
Once the requirements, design, and task list were in place, I let Kiro generate the implementation.
That gave me a useful balance between planning and automation.

💡 The Key Insight

The biggest lesson was that AI performs best when it has context.
Not:
Build me an AI recipe app.
But:
Here are the requirements, architecture, and implementation plan. Now generate the code.
The more structure I provided, the better the results became.

🚀 From Planning to Building

After generating the requirements, design documents, and task list, I decided to try something interesting.
Instead of generating code task by task, I pressed:
Run All Tasks
and let Kiro generate the entire implementation.
This turned out to be one of the most interesting parts of the project.
Not because everything worked immediately.
It didn’t.
But because it revealed exactly where AI excels and where engineering experience still matters.

👉 The Result

Using Kiro helped me:
  • Move from idea to implementation much faster
  • Avoid staring at a blank screen
  • Generate a complete project structure
  • Focus on reviewing rather than creating everything from scratch
Most importantly, it allowed me to spend more time solving problems and less time writing boilerplate.
The generated code wasn’t perfect.
But it got me surprisingly close to a working MVP.

⚙️ Step 0 — Setting Up the Project (Without AI)

Before opening Kiro, I set up the foundation myself.
There’s no reason to spend AI credits on tasks I can complete in a few seconds.
So I started with a basic Next.js application and initialized AWS Amplify Gen 2:
1
2
npx create-next-app@latest whats-in-my-fridge --yes
cd whats-in-my-fridge
1
2
npm create amplify@latestnpx ampx sandbox --once
npm run dev
This gave me:
  • A clean Next.js project
  • An Amplify Gen 2 backend structure
  • A local development environment
  • A working foundation to build on
At this point, there was nothing particularly exciting.
No AI.
No backend logic.
No database.
Just a solid starting point.
Press enter or click to view image in full size

💡 Why this matters

It’s tempting to let AI generate everything.
But that’s also the fastest way to:
  • waste credits
  • lose control
  • and end up debugging code you don’t fully understand
So instead, I used AI where it actually adds value.

🧠 My Rule

A simple rule guided this entire project:
Don’t use AI for what you already know. Use it for what you don’t want to figure out from scratch.
Creating a Next.js project and initializing Amplify takes minutes.
Designing requirements, architecture, and implementation plans takes significantly longer.
That’s where I wanted AI to help.
With the project scaffolded and Amplify running locally, it was finally time to open Kiro and turn the idea into something more concrete.

🧭 Step 1 — Define Steering and Configure MCP Servers

Before generating requirements or writing code, I followed Kiro’s recommended workflow and started with steering.
The idea behind steering is simple:
Give the AI enough context before asking it to solve a problem.
Instead of immediately generating requirements, I first defined the product vision, technical architecture, and project constraints.
This helps Kiro make better decisions throughout the entire development process.

📦 Product Steering

The product steering document describes what the application is supposed to do and who it’s for.
1
2
3
4
AI Fridge Recipe GeneratorUsers upload a fridge photo.
The system identifies ingredients and generates recipes.
Focus on minimizing additional groceries.Target audience:
People who want quick meal ideas and reduce food waste.
This gives Kiro a clear understanding of the problem we’re trying to solve.

🏗️ Technical Steering

Next, I defined the technical boundaries.
1
2
3
4
5
6
7
8
9
Frontend: Next.js
Hosting: Amplify
Auth: Cognito
Storage: S3
Compute: Lambda
Database: DynamoDB
AI: Bedrock

Architecture must be fully serverless.
This prevents the AI from suggesting technologies that don’t fit the project.
For example, I didn’t want recommendations involving Kubernetes, containers, relational databases, or complex infrastructure.
The architecture was already decided.

🚧 Constraints Steering

1
2
3
4
5
Keep MVP minimal.No social features.
No advanced analytics.
No calorie tracking.
No microservices.
No containers.
Press enter or click to view image in full size

🔌 Connecting AWS MCP Servers

With the steering documents in place, I connected two AWS MCP servers:
  • AWS MCP
  • AWS Documentation MCP
These give Kiro access to AWS-specific knowledge and documentation while working on the project.
That means it can reference AWS services, Amplify patterns, and implementation guidance directly instead of relying solely on its training data.
The configuration looked like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"mcpServers": {
"aws-mcp": {
"command": "uvx",
"timeout": 100000,
"transport": "stdio",
"args": [
"mcp-proxy-for-aws@latest",
"https://aws-mcp.us-east-1.api.aws/mcp",
"--metadata", "AWS_REGION=us-west-2"
]
},
"awslabs.aws-documentation-mcp-server": {
"command": "uvx",
"args": ["awslabs.aws-documentation-mcp-server@latest"],
"env": {
"FASTMCP_LOG_LEVEL": "ERROR",
"AWS_DOCUMENTATION_PARTITION": "aws",
"MCP_USER_AGENT": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
},
"disabled": false,
"autoApprove": []
}
}
}

⚡ Adding Amplify Gen 2 Guidance

Because this project is built entirely on Amplify Gen 2, I added an additional steering document specifically for Amplify.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Amplify Guidance

This project uses AWS Amplify Gen 2.

Requirements:

- Use Amplify Auth for Cognito authentication
- Use Amplify Storage for S3 integration
- Use Amplify Data for DynamoDB-backed data models where appropriate
- Use Amplify Functions for Lambda workloads
- Prefer Amplify-generated infrastructure over custom CDK where possible
- Follow Amplify Gen 2 TypeScript-first patterns
- Keep the solution fully serverless
- Avoid unnecessary AWS services

💡 Why This Matters

At this point, I still hadn’t generated any requirements or written any application code.
Instead, I spent time giving Kiro context.
It might feel like an extra step, but it turned out to be one of the most valuable parts of the process.
By clearly defining the product, architecture, constraints, and preferred AWS patterns up front, the requirements, design documents, and generated code were much more aligned with what I actually wanted to build.
Only after all of this was in place did I move on to generating the project requirements.

🧩 Step 2 — From Idea to Requirements (Kiro)

With the project foundation in place and the steering documents configured, it was finally time to ask Kiro for help.
One thing I deliberately avoided was jumping straight into code generation.
Instead, I wanted Kiro to answer a more important question first:
What exactly should I build?
At this stage, I already had:
  • A Next.js application
  • An Amplify Gen 2 backend
  • AWS MCP servers connected
  • Steering documents defining the product, architecture, and constraints
What I didn’t have yet was a clear implementation plan.
So I asked Kiro to generate a complete MVP specification.
Here’s the exact prompt I used:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
I want to build a minimal MVP using AWS Amplify Gen 2.App idea:
A logged-in user uploads a photo of their fridge.
The app uses Amazon Bedrock to identify likely ingredients from the image and generate one recipe that uses mostly those ingredients and minimizes extra groceries.Tech stack:
- Next.js frontend (Amplify Hosting)
- AWS Amplify Gen 2 (fullstack framework)
- Amplify Auth (Cognito)
- Amplify Storage (S3)
- Amplify Function (Lambda)
- Amplify Data (DynamoDB)
- Amazon Bedrock for image understanding and recipe generationConstraints:
- Keep the MVP as small as possible
- Fully serverless
- No social login
- No advanced UI
- No streaming
- No complex featuresPlease generate:
1. MVP requirements (functional + non-functional)
2. Non-goals
3. High-level architecture
4. API contract for the backend
5. Minimal DynamoDB data model
6. Task breakdown in the smallest possible stepsDo NOT generate code yet.
The goal wasn’t to generate code.
The goal was to transform a vague idea into a structured plan.

📋 What Kiro Generated

In a single run, Kiro produced:
  • Functional requirements
  • Non-functional requirements
  • Explicit non-goals
  • A high-level architecture
  • An API contract
  • A DynamoDB data model
  • A detailed task breakdown
This was the first moment where the project started to feel real.
Instead of wondering what to build next, I now had a roadmap.

💡 The Most Valuable Part

The requirements themselves weren’t the most valuable output.
The task breakdown was.
Kiro decomposed the application into a series of small, manageable steps that could be implemented and tested independently.
That immediately reduced the complexity of the project.
Rather than thinking about “building an AI application,” I could focus on completing one small task at a time.

🧠 What I Learned

One of the biggest lessons from this step was that AI performs much better when you ask it to structure a problem before solving it.
If I had started with:
Build me an AI fridge recipe app.
I probably would have received thousands of lines of code and very little understanding of how everything fit together.
Instead, I spent a few minutes defining the problem and asking Kiro to create a specification first.
That simple change completely altered the outcome.
Rather than generating code immediately, Kiro helped me create:
  • Clear requirements
  • Defined boundaries
  • A data model
  • An API design
  • An implementation plan
In other words:
Before writing a single line of application code, I already knew what I was going to build and how I was going to build it.
That turned out to be one of the most valuable steps in the entire project.
With the requirements finished, the next step was to generate a technical design and implementation plan.
Kiro generated a surprisingly complete specification.
The output included:
  • Functional requirements
  • Non-functional requirements
  • Explicit non-goals
  • A high-level architecture
  • An API contract
  • A DynamoDB data model
  • A detailed implementation plan
One thing I particularly liked was that Kiro didn’t just describe the application.
It also broke the project down into a sequence of small implementation tasks.
Instead of thinking about building an entire AI application, I suddenly had a checklist of manageable steps.
Here’s a small excerpt from the generated requirements:
FR-1: User can sign up and sign in with email/password (Cognito)FR-2: Authenticated user can upload a photo of their fridgeFR-3: The system identifies ingredients using Amazon Bedrock**FR-4: The system generates a recipe using mostly those ingredients
For a first draft, the output was remarkably close to what I had in mind.
Press enter or click to view image in full size

🏗️ Step 3 — From Requirements to Design

Once the requirements were approved, I asked Kiro to generate the technical design.
What impressed me most wasn’t the architecture itself — I had already decided to use Amplify Gen 2, Cognito, S3, DynamoDB, Lambda, and Bedrock.
The value came from turning those decisions into a concrete implementation plan.

📐 What Kiro Generated

Based on the requirements document, Kiro produced:
  • A complete architecture design
  • GraphQL data models
  • Storage layouts
  • Lambda responsibilities
  • Frontend component structure
  • Security and authorization rules
Instead of spending hours documenting everything manually, I could focus on reviewing the design and making a few adjustments.

🧠 What Surprised Me

The generated design was far more detailed than I expected.
Kiro didn’t just describe the application at a high level.
It made concrete implementation decisions, including:
  • Using a custom analyzeImage GraphQL mutation
  • Using a single Lambda function for the entire analysis pipeline
  • Applying owner-based authorization rules
  • Defining the DynamoDB data model
  • Designing the upload → analyze → store → display workflow
Most of these decisions aligned closely with what I would have chosen myself.

📄 Reviewing the Design

Of course, I didn’t blindly accept everything.
The design still needed review.
For example, I decided to make a few changes:
  • Store recipe data as structured JSON instead of plain text
  • Keep the MVP focused on a single recipe suggestion
  • Remove unnecessary complexity that wasn’t needed for version one
That’s where I found the real value of Kiro.
Instead of starting from a blank page, I started with a complete design and reviewed it as an engineer.

💡 The Biggest Lesson

This was the first moment where I felt Kiro shift from being a chatbot to being an engineering assistant.
The generated design wasn’t perfect.
But it was detailed enough that I could move directly into implementation planning instead of spending hours creating architecture diagrams and technical documentation myself.
And that’s where things got interesting.
The next step was generating the implementation tasks — and eventually letting Kiro build the application.
Press enter or click to view image in full size

📋 Step 4 — Generating the Implementation Plan

With the requirements and design documents completed, there was one final planning step.
I asked Kiro to generate a detailed implementation plan.
The goal wasn’t to get more documentation.
The goal was to answer a simple question:
What should I build first?

🧩 Breaking the MVP into Small Tasks

Kiro took the requirements and design documents and converted them into a structured task list.
Instead of one large project, I now had a sequence of smaller tasks that could be implemented and tested independently.
The plan covered:
  • Amplify Storage
  • Amplify Data models
  • Lambda functions
  • Bedrock integration
  • Frontend pages
  • Deployment
Most importantly, the tasks were ordered in a logical sequence.
Backend infrastructure first.
Business logic second.
Frontend implementation third.
Deployment last.

📄 A Surprisingly Detailed Output

The generated implementation plan contained dozens of individual tasks and subtasks.
For example:
  • Configure Amplify Storage
  • Create the Recipe data model
  • Implement image retrieval from S3
  • Integrate Amazon Bedrock
  • Parse and validate AI responses
  • Store recipes in DynamoDB
  • Build the upload page
  • Build the history page
  • Deploy to Amplify Hosting
This was far more detailed than a typical project checklist.

✂️ Simplifying the Plan

While reviewing the generated tasks, I noticed that Kiro had also proposed a large number of automated tests, including property-based testing.
For a production system, that might make sense.
For a weekend MVP, it felt like overkill.
So I simplified the plan and focused on what was actually needed to validate the idea:
  • Upload a photo
  • Analyze it with Bedrock
  • Generate a recipe
  • Store the result
  • Display it in the UI
Everything else could wait.

🚀 The Moment of Truth

At this point, I had:
  • A project scaffold
  • Steering documents
  • Requirements
  • A technical design
  • An implementation plan
Normally, this is where I would start implementing tasks one by one.
Instead, I decided to try something more interesting.
I pressed:
Run All Tasks
and let Kiro generate the entire application.
That’s when the real experiment began.

🚀 Step 5 — Letting Kiro Build the MVP

I spent less than an hour going from a rough idea to a reviewed implementation plan.
At that point, it was time to stop planning and start building.
Normally, I would implement the tasks one by one.
This time, I decided to run a little experiment.
Instead of generating code incrementally, I clicked:
Run All Tasks
and let Kiro generate the entire implementation.

🛟 First Things First: A Safety Net

Before letting Kiro loose on the codebase, I created a clean Git checkpoint.
If everything went horribly wrong, I wanted an easy rollback point.
That turned out to be a good decision.

⚙️ Watching Kiro Work

As the tasks started executing, Kiro occasionally asked for permission to run commands.
Things like:
  • Installing npm packages
  • Searching files
  • Reading configuration files
  • Updating project structure
My development environment runs inside my homelab, so I could literally watch the VM working while Kiro was generating code.
CPU usage went up.
Memory usage increased.
Files started appearing.
And then I waited.
Press enter or click to view image in full size

⏱️ 33 Minutes Later…

After 33 minutes and 15 seconds, every task was marked as completed.
The implementation consumed:
81.69 credits
At first glance, that sounds expensive.
But Kiro had just generated:
  • Amplify backend configuration
  • Cognito integration
  • S3 storage integration
  • DynamoDB models
  • Lambda functions
  • Bedrock integration
  • Frontend pages
  • Authentication flows
That’s a significant amount of work.
Now it was time for the real test.

🧪 First Deployment

I deployed the backend:
1
npx ampx sandbox --once
And almost immediately, the first error appeared.
Press enter or click to view image in full size

💥 Problem #1 — Circular Dependencies

Amplify complained about a CloudFormation circular dependency.
The error message was surprisingly helpful and pointed directly to the issue:
If your function is used as a data resolver or calls the data API, assign the function to the data stack.
The generated architecture wasn’t completely wrong.
It just needed a small adjustment.
Rather than fixing it manually, I asked Kiro to review the implementation and apply the minimum required change.
A few minutes later, the deployment succeeded.

🎉 First Login

After redeploying, I opened the application and was greeted by a Cognito login screen.
Press enter or click to view image in full size
A good sign.
I created a test account, logged in, uploaded a random stock photo.
Press enter or click to view image in full size
Then I hit the next problem.

💥 Problem #2 — Bedrock Model Access

The Lambda executed successfully.
The image uploaded successfully.
But Bedrock refused to cooperate.
The GraphQL response showed a model access error.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"data":{
"analyzeImage":null
},
"errors":[
{
"path":[
"analyzeImage"
],
"data":null,
"errorType":"Lambda:Unhandled",
"errorInfo":null,
"locations":[
{
"line":2,
"column":3,
"sourceName":null
}
],
"message":"Bedrock invocation failed: Model access is denied due to IAM user or service role is not authorized to perform the required AWS Marketplace actions (aws-marketplace:ViewSubscriptions, aws-marketplace:Subscribe) to enable access to this model. Refer to the Amazon Bedrock documentation for further details. Your AWS Marketplace subscription for this model cannot be completed at this time. If you recently fixed this issue, try again after 2 minutes."
}
]
}
The generated implementation was trying to use Claude Haiku, but my account didn’t have access configured for that model.
Rather than spending time configuring model access, I decided to switch to:
1
amazon.nova-2-lite-v1:0
which was also a better fit for keeping costs low.

💥 Problem #3 — Nova Request Format

The next deployment got further.
But now Bedrock complained about the request payload.
The implementation was still using a Claude-style request structure, while Nova expected a different format.
This wasn’t an architectural issue.
It was simply a mismatch between the selected model and the request body being generated.
Another prompt to Kiro.
Another fix.
Another deployment.

💥 Problem #4 — IAM Permissions

The next error looked more familiar:
User is not authorized to perform bedrock
At this point, the generated application was actually working.
The Lambda executed.
The code compiled.
The request reached Bedrock.
But the Lambda role didn’t have the required permissions.
This is where AWS experience still matters.
Kiro generated most of the infrastructure correctly, but IAM policies still needed review and adjustment.
After updating the permissions and redeploying, I moved on to the next issue.

💥 Problem #5 — Inference Profiles

The IAM policy looked correct.
Yet Bedrock still complained.
After some investigation, I discovered that Nova 2 Lite was being invoked through an inference profile rather than a direct foundation model ARN.
That required another adjustment to the permissions model.
Again, Kiro helped with the implementation, but understanding the AWS platform was what ultimately led to the solution.

🎉 First Successful Result

Eventually, I uploaded a photo and received a response.
The application successfully:
  • Uploaded the image
  • Invoked Bedrock
  • Detected ingredients
  • Generated a recipe
  • Stored the result in DynamoDB
For the first time, the end-to-end flow actually worked.
Well… mostly.
Press enter or click to view image in full size

💥 Problem #6 — The Missing Recipe

The ingredients appeared.
The recipe title appeared.
But the recipe itself didn’t render.
The History page showed useful clues, which pointed to a mismatch between:
  • The Bedrock response
  • The DynamoDB data model
  • The frontend rendering logic
Once again, Kiro helped identify the problem and normalize the data structure.
The History page started rendering correctly.
Then the Upload page was fixed as well.

🚀 A Working MVP

After a handful of targeted prompts and several deployment cycles, I finally had a working application.
I uploaded another stock photo.
The ingredients were detected.
A recipe was generated.
The result appeared in the UI.
Mission accomplished.
💰 Total credits consumed# 118.46 Credits
And while the generated code wasn’t perfect, the amount of work completed in such a short time was genuinely impressive.
More importantly, the experience highlighted something I believe will become increasingly important:
AI can generate a large portion of the implementation, but understanding cloud architecture, IAM, and platform-specific behavior is still what turns generated code into a working product.

💰 Cost of the Experiment

One question I often get when using AI coding tools is:
How many credits did it actually consume?
For this project, the breakdown looked like this:
Planning (requirements, design, tasks)
~36 credits
Initial implementation (Run All Tasks)
81.69 credits
Debugging and fixes
~37 credits
Total
118.46 credits
Was it worth it?
For me, yes.
In roughly 33 minutes, Kiro generated a complete Amplify Gen 2 application including:
  • Authentication
  • Storage
  • Lambda functions
  • Bedrock integration
  • DynamoDB models
  • Frontend pages
The generated code wasn’t perfect, but it provided a working foundation that would have taken significantly longer to build manually.
More importantly, it allowed me to focus on solving problems and validating the idea instead of spending hours writing boilerplate code from scratch.
AI didn’t replace engineering work. It accelerated it.

⚠️ What Didn’t Work (and Why That’s Okay)

AI demos often look perfect.
Reality is a little messier.
While the MVP worked surprisingly well, I quickly discovered that AI-powered image recognition isn’t magic.

1. Bad photos lead to bad recipes

The quality of the uploaded image matters a lot.
A well-lit photo with clearly visible ingredients produced much better results than a blurry or partially obstructed image.
No surprise there: if humans struggle to identify what’s in a fridge, AI will struggle too.

2. The AI occasionally hallucinated ingredients

This was probably the most interesting finding.
In one test image, the AI confidently detected ingredients that weren’t actually visible.
For example, it identified items such as chicken, soda, or spinach simply because they were plausible things to find inside a refrigerator.
This is a reminder that large language models don’t truly “see” like humans do. They make educated guesses based on patterns.

3. Infrastructure was harder than the AI

The biggest challenges weren’t actually related to prompting or image analysis.
Most of the time was spent fixing cloud infrastructure issues:
  • CloudFormation circular dependencies
  • IAM permissions for Lambda
  • Bedrock model access
  • Bedrock inference profile configuration
Ironically, generating the recipe was easier than configuring the permissions required to generate it.

4. AI-generated code still needs review

Kiro generated the majority of the application structure, but it wasn’t perfect.
Several issues required manual investigation and fixes:
  • Incorrect Bedrock model identifiers
  • Missing IAM permissions
  • Frontend/backend data format mismatches
The lesson wasn’t that AI failed.
The lesson was that AI worked best when paired with engineering knowledge.

5. Not every recipe was a masterpiece 😄

Sometimes the generated recipes were genuinely useful.
Sometimes they were… creative.
A fridge full of vegetables once resulted in a “Vegetable and Ham Sandwich” despite no obvious ham being visible.
The app was helpful, but I wouldn’t blindly trust it to plan a dinner party.
That’s exactly why keeping a human in the loop still matters.

🚀 What I Would Build Next

Now that the MVP works, there are plenty of directions I could take it:
- 📦 Barcode scanning for packaged products
- ⏰ Expiry date detection
- 🥗 Nutritional analysis
- 🛒 Automatic shopping list generation
- 📸 Improved image recognition using larger multimodal models
But for now, I’m deliberately stopping here.
The goal was to validate the idea, not build the ultimate food assistant.

🎯 Key Takeaways

After building this project, a few lessons stood out.

AI doesn’t need to be perfect to be useful

The ingredient detection wasn’t always accurate.
The model occasionally hallucinated ingredients and sometimes suggested recipes that were a little optimistic.
But that didn’t make the application useless.
In many cases, the AI only needed to be “good enough” to provide inspiration and help reduce food waste.
Perfect accuracy wasn’t required to deliver value.

Serverless makes experimentation incredibly fast

The entire application was built using managed AWS services:
  • Amplify Gen 2
  • Cognito
  • S3
  • Lambda
  • DynamoDB
  • Bedrock
There were no servers to provision, patch, or maintain.
That allowed me to focus on solving the problem rather than managing infrastructure.

Kiro is powerful, but only when used intentionally

The biggest value wasn’t having Kiro generate code.
The biggest value was using Kiro to:
  • Define requirements
  • Generate a technical design
  • Create an implementation plan
  • Scaffold the application
When problems appeared, AWS knowledge was still required to understand and fix them.
AI accelerated the work, but it didn’t replace engineering judgment.

MVP beats a perfect product

It would have been easy to spend weeks adding features:
  • Barcode scanning
  • Expiry tracking
  • Nutrition analysis
  • Shopping list generation
  • Mobile apps
Instead, I focused on one simple question:
Can I take a picture of my fridge and get a useful recipe suggestion?
The answer turned out to be yes.
And that simple MVP taught me far more than months of planning ever could.

🔚 Conclusion

This started as a simple idea:
What if I could take a photo of my fridge and let AI tell me what to cook?
A few hours later, I had a working serverless application running on AWS.
The app isn’t perfect.
It occasionally misidentifies ingredients.
It sometimes suggests questionable recipes.
And I spent more time debugging AWS permissions than writing actual code.
But that’s exactly the point.
The goal was never to build the perfect product.
The goal was to validate an idea as quickly as possible.
Using Kiro, Amplify Gen 2, Bedrock, and a fully serverless architecture, I was able to go from a rough concept to a working MVP in a surprisingly short amount of time.
Along the way I learned that:
  • AI doesn’t need to be perfect to be useful
  • Serverless dramatically reduces development overhead
  • Kiro is most valuable for planning and implementation guidance
  • Building and testing an MVP teaches more than endlessly refining an idea
Most importantly:
I now have a working application that can look inside my fridge and suggest something to cook.
And that’s a lot more useful than another unfinished side project sitting in a notebook.
Would I use Kiro again?
Absolutely.
Not because it writes perfect code, but because it dramatically accelerates the journey from idea to working software.
If you’re experimenting with AI-powered applications on AWS, my advice is simple:
Start small. Build fast. Learn from reality.

🚀 What’s Next?

The source code for this project is available on GitHub:
This started as a simple experiment to see how quickly I could go from idea to MVP using Kiro and AWS.
It definitely won’t be my last.
I’m currently exploring more projects involving:
  • AWS Amplify Gen 2
  • Amazon Bedrock
  • AI Agents
  • Serverless architectures
  • Voice AI applications
If you’d like to see more builds like this, feel free to follow me.
And if you end up building your own version, I’d love to hear about it.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article