I run a lot of meetups in Bangalore, and one thing I keep reaching for is an interactive quiz tool to break up the room and give away swag. Kahoot, Slido, and Mentimeter all do this well, but they are paid, and I wanted something I could self-host and tweak.
So I built Hoot, an open source alternative for real-time interactive quizzes. You create an event, add questions, publish it, share a QR code or join code, and the audience plays from their phones in real time. Standard format, leaderboard at the end.
Live version: hoot-the-quiz.vercel.app
Source: github.com/PriteshKiri/hoot
If you want the video walkthrough first, here it is:
The interesting part is not the app itself, it is how I built it. I used Kiro, an agentic IDE from AWS that takes a spec-first approach instead of a chat-first one. This post walks through what Hoot does, how Kiro's workflow actually shaped the build, and an honest list of the things I would want Kiro to fix.
What Hoot does
The flow is roughly what you would expect from a Kahoot-style tool.
You sign in and land on a dashboard of your events. An event is just a container for a set of questions, scoped to a single quiz session. I can spin up one called "Python Meetup" in a couple of clicks, pick a theme and gradient (I went with sunset), and start adding questions.
Each question has a type (single select or multi select), a time limit, options, and a correct answer. Once the questions are in, you publish the event. Publishing gives you a QR code and a join code. Attendees scan or enter the code, pick a name, and wait in the lobby. You start the session, everyone answers on their phones, and the leaderboard updates between rounds based on correctness and speed.
That is the whole product. Nothing groundbreaking, but it works, it is free, and the code is open.
How Kiro's spec workflow shaped the build
I have used a bunch of AI coding tools at this point. The thing that stood out about Kiro is that it does not start with code. It starts with a spec.
When I gave it my initial long prompt describing Hoot, it did not jump into a file and start writing components. It created a .kiro/specs/ folder with three files:
-
requirements.md: a structured breakdown of what the product needs to do, written in plain language -
design.md: architecture, data model, component hierarchy, all the design decisions before code -
tasks.md: a prioritized task list, with optional items called out separately
The task list is the part that surprised me.
It was comprehensive and accurate, broken into small chunks that Kiro then worked through one at a time, checking each off as it went. It behaves the way a careful engineer would: plan, decompose, execute, mark done. Not the usual "here is a 400-line file, hope it compiles" pattern.
Alongside the specs, Kiro created a steering/ folder with three files: product.md, structure.md, and tech.md. These are persistent context documents. product.md describes what the product is and who it is for. structure.md describes the codebase layout. tech.md locks in the stack. Once these exist, every future prompt is automatically grounded in them, so I do not have to keep re-explaining what the project is.
For Hoot, the stack ended up being Next.js, Tailwind, and Supabase for auth, database, and real-time. The real-time piece is what makes the quiz sessions work: players joining the lobby, answers coming in, and leaderboard updating live.
The build itself took roughly two weeks of part-time work. I will note that it also burned through five free accounts because each one only gives you 50 credits, and Hoot was not a 50-credit project.
Powers and MCP
The other Kiro feature I leaned on was Powers.
Powers are how Kiro handles external tools and integrations. The usual problem with hooking an agent up to a lot of MCP servers is context overload. If your agent has access to twenty tools all the time, every request burns context just deciding what is relevant, and responses get slower and less accurate.
Kiro's approach is to load the tool context on demand. When you submit a prompt, Kiro analyzes the task and only activates the Powers relevant to it. For Hoot, that meant the Supabase Power was active when I was working on schema changes or realtime subscriptions, and stayed out of the way otherwise.
The Powers panel comes with a catalog you can install from: Supabase, Neon, Netlify, Postman, Datadog, Figma, and so on. The installation is one click, and the configuration is a short form. I had Supabase running natively inside the IDE in under a minute, which meant Kiro could run SQL migrations and schema scripts directly instead of me copy-pasting between windows.
What I would want Kiro to do better
I want to be honest here because the experience was not all smooth. A few things got in my way.
No "always allow" for permissions. Every action Kiro takes asks for explicit approval. For an agentic IDE that is supposed to plan and execute, sitting there clicking accept every few seconds breaks flow. Cursor and Claude Code both have a permission tier system for this. Kiro should too.
Chat history disappears when context fills. When a chat hits the context limit, Kiro carries the relevant context forward into a new chat, but the old chat is gone. I lost visibility into the prompts I had given earlier, which is a problem when I am trying to remember why a decision was made. The summary should be carried forward, the chat itself should be archived, not deleted.
File references in responses are not clickable. When Kiro mentions a file in its response, I have to navigate to it manually in the explorer. Other IDEs make those references jump-to links. Small thing, high friction.
No voice input. I do a lot of coding by talking through what I want now. Having to type long prompts feels backwards. Voice would be a real upgrade.
Powers awareness is inconsistent. Sometimes Kiro forgets which Powers are installed in the workspace and I have to explicitly tell it "use the Supabase Power for this." It should know. This might be a free plan limitation but it was noticeable.
It pulled in outdated dependencies. When Kiro initialized the project, it did not pick the latest stable versions of Next.js, Tailwind, and a few other packages. I had to manually bump them later. For a tool that is supposed to scaffold production-ready apps, this should be a default.
It was slow at times. Not catastrophically, but enough that I noticed. Sometimes a simple prompt would take a long time to start streaming. I never figured out a pattern for when this happened. May be beacause of the free plan.
Images take up too much space in chat. When I drop a screenshot into the chat, it eats half the panel. Thumbnails with click-to-expand would be much better.
No "intent" selector for new chats. When I start a new chat, Kiro has no idea whether I am fixing a bug, refactoring, or adding a feature. A small dropdown at the top of a new chat to set the intent (bug fix, feature work, refactor, doc update) would give the agent a useful prior and probably improve responses without me having to spell it out every time.
Closing
For all the rough edges, building Hoot in Kiro was genuinely a different experience from chat-first tools. The spec-driven flow forced me to think through the product before generating code, which meant the code I got was more coherent than the usual scattered output. The steering files meant Kiro stayed on track across sessions. The Powers system kept context clean.
If you organize meetups, conferences, or workshops and want a quiz tool you can self-host and modify, take Hoot for a spin. PRs welcome.
- Hoot on GitHub: github.com/PriteshKiri/hoot
- Hoot live: hoot-the-quiz.vercel.app
- Kiro: kiro.dev


Top comments (0)