Every company has that internal tool. You know the one. Built in 2010, looks like it was designed by someone who hated their coworkers, and somehow still runs critical business operations.
The backend works fine. The API is solid. But the UI? It's a crime against humanity.
We decided to fix this problem for Kiroween 2025 and in the process, discovered why spec-driven development might be the most underrated approach to building software.
The Problem We Wanted to Solve
Here's the painful reality: companies spend $10K+ and months of developer time rewriting internal tools. The UI looks like it was designed to punish employees. The API throws CORS errors when you try to call it from anything modern. Field names are cryptic nightmares like usr_acct_sts_cd. And good luck figuring out the authentication scheme.
What if you could just... generate a new UI that handles all of this? Point at an API, click a button, and get a modern React dashboard with a smart proxy that deals with auth, CORS, and field name translation?
That's what we built: Legacy UX Reviver.
What It Actually Does
- Analyze any API - Paste an OpenAPI spec, connect to a live endpoint, or just drop in a JSON sample
- Review and customize the schema - Edit field names, hide sensitive data, configure CRUD operations
- Generate a complete portal - Dashboard, data grids, forms, the works
- Deploy anywhere - Browser preview, download as ZIP, or one-click Vercel deployment
The whole flow takes about 30 seconds. No backend changes required.
Why We Chose Spec-Driven Development
Here's where it gets interesting. We didn't just dive into code. We used Kiro and its spec-driven approach, and honestly? It changed how we think about building features.
What Even Is Spec-Driven Development?
Instead of jumping straight to code, you start by defining:
- Requirements - What problem are we solving? What are the acceptance criteria?
- Design - How will we solve it technically? What's the architecture?
- Tasks - What are the concrete implementation steps?
Kiro keeps these specs in your project and uses them to guide development. It's like having a technical design doc that actually stays in sync with your code.
Our Specs Folder Structure
.kiro/specs/
├── api-introspection/ # How we analyze APIs
├── smart-proxy-layer/ # The proxy that handles auth + CORS
├── ui-generation/ # Portal component generation
├── vercel-deployment/ # One-click deployment
└── schema-customization/ # Field editing features
Each folder has requirements.md, design.md, and tasks.md. Sounds like overhead, right? Here's why it wasn't.
The Moment Spec-Driven Development Saved Us
One of us was building the API analyzer - the core feature that parses OpenAPI specs and extracts resources. The first instinct was to just start coding.
But we forced ourselves to write the spec first. Take, for example, our process to write the API Introspection Engine.
API Introspection Engine
Input: API base URL + authentication
Output: Normalized schema representation
Process:
- Enumerate endpoints (common patterns)
- Sample requests to understand structure
- Infer field types from data
- Detect relationships between resources
- Generate internal schema JSON
Writing this out made us realize we needed to handle 8 different input modes:
- OpenAPI spec (JSON/YAML)
- OpenAPI URL
- Live endpoint probing
- JSON sample
- WSDL file
- WSDL URL
- SOAP endpoint
- XML sample
If we'd just started coding, we would've built the OpenAPI parser, then realized we needed endpoint probing, then hacked in SOAP support as an afterthought. The spec forced us to think about the full scope upfront.
How Kiro Actually Helped
Kiro isn't just a spec organizer - it's an AI-powered IDE that uses your specs as context. Here's what that looks like in practice:
Steering Rules
We set up "steering" files that Kiro references during development:
# frontend-coding-standards.md
## Spooky Theme Requirements (Analyzer Only)
- Background: `bg-gradient-to-br from-slate-950 via-purple-950 to-slate-950`
- Primary Color: Green (`text-green-500`, `bg-green-600`)
- Icons: Lucide React (Skull, Ghost for spooky elements)
## Modern Theme Requirements (Generated Portal Only)
- Background: Light mode (`bg-white`, `bg-gray-50`)
- Style: Clean, professional, modern SaaS aesthetic
Every time we asked Kiro to help with a component, it already knew the design system. No more "make it match the rest of the app" back-and-forth.
Hooks for Automation
We configured hooks that run automatically:
- lint-on-save - Auto-fix TypeScript and Python on save
- build-check - Verify the frontend builds before commits
Small things, but they kept the codebase clean without us thinking about it.
MCP
We used the Context7 MCP so that we could rely on the latest documentation for some libraries that we wanted to use.
Context That Actually Helps
The killer feature? Kiro understands the whole project. When we were building the proxy layer, it knew:
- The frontend expects responses in a specific format
- The backend analyzers return
ResourceSchemaobjects - The proxy needs to handle Bearer, API Key, Basic, and WSSE auth
We didn't have to re-explain context every time. The specs and steering files did that for us.
The Architecture That Emerged
Here's what the final system looks like:
User → Landing Page → Analyzer (REST/SOAP) → 3-Step Flow → Generated Portal
↓
1. Schema Review
2. UI Customization
3. Deploy (Browser/Download/Vercel)
↓
Generated Portal ← Proxy Server → Legacy API
The Smart Proxy Layer
This was the trickiest part. The generated portal needs to talk to legacy APIs, but:
- CORS blocks browser requests
- Legacy APIs have weird auth (WSSE anyone?)
- Field names are often cryptic (
usr_nminstead ofuserName)
The proxy sits between the frontend and legacy API, handling all of this:
// Frontend calls the proxy
GET /api/proxy/users
// Proxy adds auth, maps fields, forwards to legacy API
GET https://legacy.company.com/api/v1/GetAllUsers
Authorization: Bearer <token>
// Proxy normalizes response and returns clean JSON
What We'd Do Differently
More Specs Earlier
We wrote specs for the big features but skipped them for smaller ones. Mistake. Even a 5-minute spec for "CSV export" would've saved us from refactoring later.
Tighter Design-to-Task Flow
Sometimes we'd write a design doc, then the tasks wouldn't quite match. Kiro helps with this, but we needed to be more disciplined about keeping them in sync.
The Results
- ✅ Upload API spec → Working portal in < 30 seconds
- ✅ Zero backend code changes required
- ✅ Works with REST and SOAP APIs
- ✅ One-click Vercel deployment
- ✅ 219 passing tests on the backend
Try It Yourself
The whole project is open source. If you've got a legacy API that needs a facelift:
- Clone the repo
- Run the frontend (
npm run dev) - Run the backend (
uvicorn app.main:app) - Paste your OpenAPI spec
- Get a modern UI
Final Thoughts on Spec-Driven Development
We went into this hackathon thinking specs were "extra work." We came out realizing they're actually less work - just front-loaded.
When you write a spec:
- You catch design issues before writing code
- You have documentation that stays useful
- AI tools like Kiro can actually help you (because they have context)
- You don't forget edge cases
Will we use spec-driven development for every project? Probably not for a quick script. But for anything with multiple features, multiple files, or any complexity at all? Absolutely.
The dead UIs of the world don't stand a chance. 💀
Built for Kiroween 2025. If you're interested in Kiro and spec-driven development, check out kiro.dev.





Top comments (0)