DEV Community

Sumin Kim
Sumin Kim

Posted on

Building a Kiroween Avatar Maker with Kiro 👻 + 4S Playbook

Github Link: https://github.com/moolmin/kiro-avatar-creator
Live Link: https://kiroween-avatar.vercel.app/

Introduction

Hackathons make you choose: ship fast or ship clean. I wanted both. So I built a Kiroween Avatar Maker for Kiroween and ran the whole thing through Kiro with a simple approach I call 4S — Specs, Steering, Spooks, Smooth UX.

  • Specs to keep scope tight and progress visible.
  • Steering for standard commits that point the way
  • Spooks to layer in the Halloween vibe without hurting usability.
  • Smooth UX to make every interaction snappy, accessible and exportable.

Here’s the exact flow, the files I wrote, the tests I used, and the few things I’d do differently next time.


Development

1) Specs

Folders

.kiro/specs/halloween-ghost-avatar/
  requirements.md
  design.md
  tasks.md
Enter fullscreen mode Exit fullscreen mode

Requirements (12 user stories, all measurable)
Requirements (12 user stories, all measurable)
Each story had clear acceptance criteria. A typical one:

  • When a user picks an eye option, the preview updates within 100 ms. Checks: no layout shift, other parts stay put, keyboard users can do the same action.

Other criteria covered exports, layering, responsiveness, and accessible controls

Design (tiny but specific)

  • Stack: Next.js 14 + TypeScript (strict) + Tailwind
  • State: Zustand with a single AvatarConfiguration (eyes, hat, cape, accessory, background)
  • Rendering: SVG components per part
  • Registry pattern: IDs → components so assets are plug‑and‑play

2) Spec‑based implementation

Kiro systematically implemented features following tasks.md:

- [ ] 1. Initialize Next.js project and install dependencies
  - Create Next.js 14 app with TypeScript and Tailwind CSS
  - Install required packages: zustand, html2canvas, downloadjs, @headlessui/react, fast-check
  - Configure TypeScript with strict mode
  - Set up Tailwind configuration
  - _Requirements: All_

- [ ] 2. Create type definitions and core interfaces
  - Define GhostPartProps interface for SVG components
  - Define AvatarConfiguration interface for state management (eyes, hat, cape, accessory, background)
  - Define ComponentRegistryEntry and CategoryRegistry interfaces
  - Create utility types for component mapping
  - _Requirements: 10.3, 11.5_

{...}

- [ ] 25. Final checkpoint - Ensure all tests pass
  - Ensure all tests pass, ask the user if questions arise.
Enter fullscreen mode Exit fullscreen mode

For each step I kicked off the task, gave the code a quick once‑over (type‑check, lint, unit tests), and made a commit using the task’s title. That kept a clean one‑task‑one‑commit history and made reviews dead simple.

3) Steering document

I wrote a short Steering document to standardise commit messages. The goal was simple: make the git history read like the spec. Each change starts from tasks.md, passes a quick check (type, lint, tests), then lands as one task, one commit. Messages follow Conventional Commits, so they’re easy to scan and trivial to filter.

# Commit Message Guidelines

When the user asks for a commit message recommendation, always provide a concise English version following these rules:

## Format
Use conventional commits format:
- `feat:` for new features
- `fix:` for bug fixes
- `refactor:` for code refactoring
- `style:` for styling changes
- `docs:` for documentation
- `chore:` for maintenance tasks
{...}
## Style
## Examples
Enter fullscreen mode Exit fullscreen mode

4) Vibe mode

UI/UX

  • Header with a simple logo; cleaner layout.
  • Export button simplified (text only) — clearer and less noisy.
  • Responsive: stacked controls on mobile; split‑pane on desktop.
  • Headless UI for menus, so keyboard users aren’t second‑class.

Assets

  • Removed the none background to avoid confusing blank exports.
  • Added more eyes, hats, capes, and accessories as first‑class SVG components.

Testing

  • Vitest + per‑component tests (*.test.tsx).
  • Basic accessibility test (accessibility.test.tsx) for labels, roles and focus order.

Why Kiro mattered

  • Specs made me faster. Clear user stories + acceptance criteria meant fewer rewrites and easier decisions.
  • The registry pattern scales. New assets drop in without changing business logic.
  • Properties catch weirdness. Layering, export fidelity, performance budgets — tested, not hoped.
  • Hybrid flow wins. Spec mode gave me guardrails; vibe mode gave me speed and personality.

What I’d tweak next time

  • Start property tests earlier so they grow with the parts library.
  • Bake a tiny a11y checklist straight into tasks.md.
  • Timebox SVG optimisation so it doesn’t steal attention from UX details.

Top comments (0)