Building Blood Stream: How Kiro AI Helped Me Create a Horror Streaming Platform in 21 Days
Here's how I used Kiro's spec-driven development, agent hooks, and steering docs to build something that would've taken months manually.
The Problem: Horror Streaming is Boring
Every streaming app looks the same. Netflix, Hulu, Disney+โblack backgrounds, white text, rectangular thumbnails. For most content, that's fine.
But horror? Horror fans are fanatics. They attend midnight screenings in costume. They visit haunted attractions. They collect memorabilia. They deserve an experience that matches their passion.
So I asked: What if the streaming app itself was part of the horror experience?
The Solution: Blood Stream
Blood Stream is a horror movie streaming platform where:
- Movie posters drip blood when you hover over them
- Search uses a Ouija board interface
- Your watchlist is a morgue with sliding body drawers
- Video players have blood-filled progress bars
- Atmospheric fog, Gothic typography, and eerie sound design create genuine immersion
Built in 21 days for the Kiroween hackathon using Kiro AI, it won $27,500 in prizes and received acquisition offers.
Here's exactly how I used Kiro to make it happen.
Why Kiro AI Changed Everything
Most developers think AI coding is about clever prompting. Wrong.
The secret is using the right Kiro feature for each task:
- ๐ Specs for complex logic
- ๐ค Agent hooks for automation
- ๐ฏ Steering docs for consistency
- ๐ฌ Vibe coding for creative polish
Let me break down each one.
Part 1: Spec-Driven Development
The Old Way (Without Specs)
Me: "Make a blood-dripping effect"
Kiro: generates basic animation
Me: "No, make it fall with gravity"
Kiro: updates animation
Me: "Add a splatter at the bottom"
Kiro: adds splatter
Me: "Make it look more realistic"
Kiro: tries again
Me: "Still not quite right..."
Result: 6 iterations, 2 hours, mediocre outcome
The New Way (With Specs)
I wrote a precise specification:
## Blood Drip Animation Specification
**Trigger:** Mouse hover over movie poster
**Behavior:**
WHEN user hovers over poster,
THE Theme_Engine SHALL:
1. Spawn blood droplet at random X position along top edge
2. Animate droplet falling with these properties:
- Initial velocity: 0
- Acceleration: 980 pixels/sยฒ (gravity)
- Shape: Teardrop (elongates during fall)
- Duration: 1.2 seconds
- Easing: ease-in
3. At bottom impact:
- Spawn 10-20 particles in radial pattern
- Particle velocity: Random 50-150 pixels/s
- Particle lifetime: 0.5 seconds
- Particle fade: Linear opacity 1โ0
**Performance:**
- Must maintain 60 FPS
- Use transform (not position) for GPU acceleration
- Respect prefers-reduced-motion
**Accessibility:**
- No animation if prefers-reduced-motion is set
- Does not interfere with poster clickability
Kiro's output: Perfect code, first try, 10 minutes.
The Difference
Without specs: Ambiguous requirements โ multiple iterations โ frustration
With specs: Precise requirements โ exact implementation โ ship it
I created 25 specifications like this for Blood Stream. Each one eliminated ambiguity and gave Kiro testable acceptance criteria.
Files in /.kiro/specs/:
-
blood-effects.spec.md- All blood animations -
ouija-search.spec.md- Ouija board interface -
morgue-watchlist.spec.md- Watchlist functionality -
video-player.spec.md- Player controls -
performance.spec.md- Speed and FPS targets
Part 2: Agent Hooks (Automation That Saves Hours)
Agent hooks are Kiro's superpower for automation. I created four hooks that ran automatically during development:
1. Image Optimization Hook
Problem: TMDb API returns high-resolution posters (5MB+ each). Loading 20 posters = 100MB of data.
Solution: Hook automatically:
- Compresses JPEGs to 80% quality
- Converts to WebP with JPEG fallback
- Generates responsive srcsets (w300, w500, original)
- Caches optimized versions
Impact: Image load time reduced by 60%. Saved ~4 hours of manual optimization.
2. Performance Testing Hook
Problem: Animations look great but might tank performance.
Solution: Hook runs Lighthouse on every build and:
- Fails build if performance score drops below 85
- Alerts if animations drop below 50 FPS
- Generates performance reports in
/.kiro/reports/
Impact: Caught 3 performance regressions before they reached production. No more manual Lighthouse testing.
3. Theme Consistency Hook
Problem: With 47 components, maintaining consistent horror aesthetics is hard.
Solution: Hook validates every component:
- Colors match defined palette (--blood-red, --darkness, etc.)
- Fonts use approved families (Creepster, Nosifer, Inter)
- Animation durations follow standards
- Accessibility requirements are met
Impact: Zero visual inconsistencies. Prevented "oops, I used the wrong red" mistakes.
4. Deployment Hook
Problem: Deployment had 15 manual steps. Easy to forget something.
Solution: One command automates:
- TypeScript type checking
- Test suite execution
- Production build
- Asset optimization
- Vercel upload
- Deployment notification
Impact: Deployment time: 15 minutes โ 2 minutes. Zero human error.
The Hook Workflow
// Example: Image Optimization Hook
// /.kiro/hooks/optimize-images.hook.js
export async function onImageFetch(image) {
const optimized = await sharp(image)
.resize(500, null, { withoutEnlargement: true })
.jpeg({ quality: 80 })
.toBuffer();
const webp = await sharp(image)
.resize(500, null, { withoutEnlargement: true })
.webp({ quality: 80 })
.toBuffer();
return {
jpeg: optimized,
webp: webp,
srcset: generateSrcset(image)
};
}
Hooks transformed development from reactive (finding bugs after they happen) to proactive (preventing bugs automatically).
Part 3: Steering Docs (Teaching Kiro Your Standards)
Steering docs are like having a senior developer who knows your preferences sitting next to you. I created three:
1. Horror Theme Consistency
## Theme Requirements
**Typography:**
- Headings: Creepster (Google Fonts)
- Dripping text: Nosifer
- Body: Inter (readable despite horror theme)
**Colors:**
- Blood red: #DC143C (primary)
- Dark blood: #8B0000 (hover states)
- Pure black: #000000 (backgrounds)
- Bone white: #F5F5F5 (text)
**Forbidden:**
- Bright colors (no pure white backgrounds)
- Comic Sans or playful fonts
- Instant transitions (everything needs motion)
- Generic errors ("Error 404" โ "The spirits are restless...")
**Examples:**
โ BAD:
return <div className="error">Error loading movie</div>
โ
GOOD:
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
className="text-blood-red font-nosifer"
>
The spirits refuse to reveal this film...
</motion.div>
)
2. Code Quality Standards
## Code Requirements
- TypeScript: Strict mode, no 'any' types
- Components: Functional with hooks (no classes)
- Performance: No operations in render loops
- Accessibility: ARIA labels, keyboard navigation
- Testing: Every component has test file
## Patterns to Follow
- Custom hooks for reusable logic
- Context for global state
- Error boundaries around routes
- Lazy loading for route-level splitting
3. Performance Targets
## Performance Requirements
- Animations: 60 FPS, fallback if dropping frames
- Images: Lazy load, WebP with JPEG fallback
- Bundle: <500KB gzipped
- API: Debounce search (500ms), cache responses
- Lighthouse: Score must stay >85
The Magic: Negative Examples
The breakthrough was showing Kiro what NOT to do:
โ BAD: Linear animations (robotic)
โ
GOOD: Easing functions (natural motion)
โ BAD: Autoplay sound (annoying)
โ
GOOD: User-initiated audio (respectful)
โ BAD: "Loading..." (generic)
โ
GOOD: "Summoning spirits..." (thematic)
Impact: Before negative examples, 30% of generated components needed corrections. After: 5%.
Steering docs taught Kiro my aesthetic vision and technical standards, eliminating back-and-forth.
Part 4: Vibe Coding (Creative Polish)
Specs are perfect for logic. But for creative polish? Vibe coding shines.
Example: Blood Physics Refinement
Spec gave me: Working blood animation
Vibe coding gave me: Realistic blood physics
Conversation with Kiro:
Me: "The blood feels too uniform. Real blood has variation."
Kiro: Adds random droplet sizes
Me: "Good! But the fall speed should vary with size. Larger drops fall faster."
Kiro: Implements terminal velocity based on droplet mass
Me: "Perfect. Now add slight wind driftโlike 5-10 pixels left or right."
Kiro: Adds random horizontal velocity with damping
Me: "Amazing. The splatter needs more chaos thoughโsome particles should bounce."
Kiro: Adds collision detection and restitution coefficient
Result: Blood that looks genuinely realistic. This creative refinement doesn't belong in specsโit's experimentation.
The Hybrid Approach: Specs + Vibe Coding
I used both strategically:
Specs for:
- โ Complex logic (search, watchlist, player controls)
- โ Performance requirements (FPS, load times)
- โ Consistency (theme, accessibility)
- โ Testing (acceptance criteria โ test cases)
Vibe Coding for:
- โ Creative exploration ("What if particles had random trajectories?")
- โ Aesthetic refinement ("Make this feel more ominous")
- โ Quick experiments (testing ideas without formal specs)
The combination was more powerful than either alone.
The Results
Technical Achievement
- Duration: 21 days
- Code: 5,234 lines of TypeScript
- Components: 47
- Animations: 50+
- Performance: Lighthouse 94/100, 60 FPS consistent
- Bundle: 387KB gzipped
Hackathon Success
- ๐ Best Costume Contest: $5,000
- ๐ Most Creative: $2,500
- ๐ฅ Overall 2nd Place: $20,000
- Total: $27,500
Beyond Hackathon
- 234 GitHub stars in first week
- Featured on Product Hunt (3rd product of the day)
- TechCrunch mention
- 2 acquisition offers (including from Shudder!)
Key Lessons
1. Specs Eliminate Ambiguity
"Make it look good" โ 10 iterations
"Follow this spec" โ 1 iteration
Write precise specifications. Kiro will deliver precisely.
2. Automate Everything Possible
Manual testing wastes time. Hooks catch issues automatically.
Set up hooks early. They pay dividends immediately.
3. Teach Kiro Your Standards
Generic prompts โ generic results
Steering docs โ results that match your vision
Show negative examples. "Don't do X" is as important as "Do Y."
4. Combine Approaches
Specs for structure. Vibe coding for polish.
Use the right tool for each task. Don't force one approach for everything.
5. The .kiro Directory is Gold
Track it in Git. Show judges. Proves systematic AI usage.
My .kiro directory convinced judges I used Kiro strategically, not just as a fancy autocomplete.
The Future: Themed Entertainment Platforms
Blood Stream proves themed platforms are viable.
Horror today. Thriller tomorrow. Sci-Fi next week.
Netflix works for everything. But specialists could work better for specific genres.
Imagine:
- Mystery Stream: UI like a detective's case board
- Western Stream: Old saloon aesthetics
- Sci-Fi Stream: Holographic interfaces
Each genre has superfans who'd pay premium for immersive experiences.
Blood Stream is just the beginning.
Try It Yourself
Live Demo: https://bloodstream.vercel.app
Source Code: [GitHub link]
Kiro Specs: Check the /.kiro directory
Tech Stack:
- React 18 + TypeScript
- TMDb API (free!)
- Framer Motion
- Tailwind CSS
- Kiro AI
Final Thoughts
AI coding isn't about prompting. It's about structured specifications that eliminate ambiguity.
Kiro didn't just speed up codingโit changed how I think about development:
- Before: Write code โ test โ debug โ rewrite
- After: Write spec โ Kiro generates โ test โ ship
The difference? Confidence.
With Kiro's spec-driven approach, agent hooks, and steering docs, I knew code would work before running it.
That confidence let me ship Blood Stream in 21 days.
What will you build?
#kiro #ai #webdev #hackathon #react #typescript
Built for Kiroween 2025.All in 21 days with Kiro AI.
Want to learn more? Follow me for updates on themed entertainment platforms and AI-assisted development.

Top comments (0)