Inspiration

Halloween has always been about storytelling - gathering around to share spooky tales that send shivers down your spine. We wanted to bring this tradition into the AI age by creating an interactive experience where anyone could summon their own personalized spooky stories. The idea was to combine the magic of AI-generated content with a fully immersive Halloween atmosphere, complete with eerie visuals, haunting narration, and a user experience that feels like opening an ancient, enchanted storybook.

What it does

Spooky Storybook is an AI-powered Halloween story generator that creates complete multimedia experiences:

  • Story Generation: Users enter a prompt and receive a unique ~250-word spooky story generated by Claude 3 Sonnet, following specific Halloween-themed guidelines
  • Visual Storytelling: Each story comes with a custom atmospheric image created by Amazon Titan Image Generator
  • Audio Narration: Stories are narrated using Amazon Polly with spooky voice effects and an animated audio visualizer
  • Story Library: A searchable, paginated collection of all generated stories with a 3x3 grid layout
  • Rate Limiting: Smart abuse prevention using dual tracking (cookies + IP) limiting users to 6 stories per 48 hours
  • Admin Panel: Secure management interface for creating, editing, and deleting stories manually

The entire experience is wrapped in a spooky-themed UI with animated backgrounds, a peeping ghost that follows your cursor, and Halloween-inspired styling throughout.

How we built it

Tech Stack:

  • Frontend: Next.js 16, React 19, Framer Motion for animations
  • Backend: Next.js API routes, SQLite (better-sqlite3) for data persistence
  • AI Services: AWS Bedrock (Claude 3 Sonnet for stories, Amazon Titan for images), Amazon Polly for narration
  • Storage: Amazon S3 for generated images and audio files

Architecture: We built a serverless architecture using Next.js API routes that integrate with AWS services. The SQLite database stores stories and rate limit tracking. The frontend uses React hooks for state management and CSS3 for spooky animations.

How We Used Kiro

Vibe Coding: Conversational Development

Approach: We used natural, iterative conversations with Kiro to build features incrementally. Rather than writing detailed specs upfront, we described what we wanted and refined through dialogue.

Example - Peeping Ghost Component: We simply said "create a ghost that peeks from the side and follows the cursor" and Kiro generated a complete component with smooth animations, multiple variants (peek, float, follow), and proper React hooks. The back-and-forth refinement (adjusting speed, adding pause functionality) felt like pair programming.

Most Impressive Generation: The audio visualizer with 20 animated bars that respond to narration playback. Kiro generated the entire implementation including CSS animations, audio event listeners, and state management in one go - it just worked.

Conversation Structure:

  1. Start with high-level feature description
  2. Review generated code
  3. Request specific refinements ("make it spookier", "add orange glow")
  4. Iterate until perfect

This approach was incredibly fast for UI components and styling where visual feedback drives decisions.

Spec-Driven Development: Structured Implementation

When We Used It: For complex features with multiple moving parts (rate limiting, search/pagination, admin panel), we switched to spec-driven development.

Process:

  1. Requirements Phase: Kiro helped create EARS-formatted requirements with user stories and acceptance criteria
  2. Design Phase: Generated comprehensive design docs with architecture diagrams, data models, and API contracts
  3. Tasks Phase: Broke down implementation into discrete, numbered tasks with requirement references
  4. Execution: Implemented tasks one at a time with clear success criteria

Example - Rate Limiting Spec:

  • Requirements: 8 user stories with 30+ acceptance criteria
  • Design: Complete architecture with database schema, dual-tracking logic, and security considerations
  • Tasks: 6 major tasks broken into 25 sub-tasks
  • Result: Zero bugs, implemented in one session

Comparison to Vibe Coding:

  • Vibe Coding: Faster for simple features, more creative, better for UI/UX
  • Spec-Driven: Better for complex logic, fewer bugs, easier to review, more maintainable
  • Best Practice: Use specs for backend/logic, vibe coding for frontend/styling

Steering Documents: Consistent AI Behavior

Primary Steering Doc: story-style.md This document defines the AI's storytelling personality and is automatically included in every story generation request.

Content:

- Tone: Spooky but not terrifying (think "Goosebumps")
- Length: ~250 words
- Theme: Halloween (ghosts, pumpkins, black cats, haunted houses)
- Ending: Mysterious or slightly funny
- Format: ONLY the story, no preamble

Impact: Before steering: Stories were inconsistent - sometimes too scary, sometimes too long, often included meta-commentary like "Here's a story about..."

After steering: Every story perfectly matched our requirements without additional prompting. This saved countless tokens and eliminated post-processing.

Strategy: We learned to put ALL consistent requirements in steering docs rather than repeating them in prompts. This made the steering doc the "personality" of our AI.

MCP: AWS Documentation Integration

Setup: We configured the AWS Documentation MCP server to access AWS service documentation directly within Kiro.

Use Cases:

  1. Bedrock API Reference: When implementing Claude 3 Sonnet integration, we used MCP to quickly look up the exact request format, parameter names, and response structure without leaving the IDE.

  2. Polly Voice Options: Searched AWS Polly docs to find the best voice for spooky narration and learned about SSML tags for adding effects.

  3. S3 Upload Patterns: Referenced S3 documentation for the @aws-sdk/lib-storage Upload class when implementing image storage.

Workflow Improvement: Instead of context-switching to a browser, searching AWS docs, and copying information back, we asked Kiro to "check AWS docs for Bedrock Claude request format" and got instant, accurate answers. This kept us in flow state.

Most Valuable: When debugging AWS SDK errors, MCP let us quickly verify we were using the correct API version and parameter structure, cutting debugging time significantly.

Development Workflow

Typical Session:

  1. Planning: Describe feature in natural language (vibe coding)
  2. Complex Features: Ask Kiro to create a spec if needed
  3. Implementation: Let Kiro generate code with steering docs active
  4. Refinement: Iterate through conversation
  5. Documentation: Ask Kiro to update README/specs

Productivity Gains:

  • 80% faster feature implementation compared to manual coding
  • Near-zero boilerplate writing (Kiro handles it all)
  • Consistent code style across the entire project
  • Better documentation (Kiro generates as it builds)

Key Insight: The combination of vibe coding for speed, specs for complexity, steering for consistency, and MCP for reference created a development experience that felt like having an expert pair programmer who never gets tired.


Total Development Time: ~72 hours for a production-ready application with 5 major features, complete documentation, and polished UI - a testament to Kiro's power when used effectively.

Challenges we ran into

1. Rate Limiting Complexity Implementing robust rate limiting that couldn't be bypassed was tricky. We needed to track both cookies and IP addresses, handle window resets, and provide friendly user feedback. The dual-tracking approach required careful database design and edge case handling.

2. AI Content Consistency Getting Claude to consistently generate stories in the right format (no meta-commentary, proper length, appropriate spookiness level) required iterative prompt engineering and steering document refinement.

3. Multimedia Synchronization Coordinating the generation of stories, images, and audio in parallel while handling failures gracefully was complex. We used Promise.all with individual error handling to ensure one failure didn't break the entire experience.

4. Search Performance Implementing efficient search with pagination required careful SQL query optimization and proper indexing to maintain performance as the story library grows.

Accomplishments that we're proud of

1. Seamless AI Integration We successfully integrated three different AWS AI services (Bedrock Claude, Bedrock Titan, Polly) into a cohesive user experience where the AI feels magical rather than mechanical.

2. Robust Rate Limiting Our dual-tracking rate limiting system effectively prevents abuse while maintaining a friendly, themed user experience. The spooky modal with floating ghosts turns a restriction into a delightful interaction.

3. Complete Feature Set We built a production-ready application with authentication, CRUD operations, search, pagination, and multimedia generation - all with a polished, themed UI.

4. Spec-Driven Development We created comprehensive specifications for major features (rate limiting, search/pagination, admin panel) following EARS requirements format, which dramatically improved code quality and implementation speed.

What we learned

1. Steering Documents are Powerful Creating a dedicated steering document (.kiro/steering/story-style.md) for story generation guidelines was game-changing. It ensured consistent AI output without repeating instructions in every prompt.

2. Spec-Driven Development Scales For complex features like rate limiting, starting with a detailed spec (requirements → design → tasks) resulted in cleaner code and fewer bugs compared to ad-hoc "vibe coding."

3. AWS Bedrock's Versatility We learned how to effectively use multiple Bedrock models in one application, handling their different response formats and error modes gracefully.

4. Rate Limiting Best Practices Implementing production-grade rate limiting taught us about window calculations, UPSERT patterns, and the importance of dual-tracking for security.

What's next for Spooky Storybook

Short-term:

  • User accounts with personalized story collections
  • Social sharing features for favorite stories
  • More voice options and languages for narration
  • Story categories and tags for better organization

Long-term:

  • Collaborative storytelling where users can continue each other's stories
  • Story remix feature to regenerate with different styles
  • Mobile app with offline story reading
  • Integration with smart speakers for audio-only experiences
  • Premium tier with higher rate limits and exclusive features

Built With

Share this project:

Updates

Submission history