Building quiz funnels in React typically means either importing a heavyweight third-party widget or writing a state machine from scratch. quiz-ui takes a different approach: it provides Radix-based components distributed the same way shadcn/ui distributes its components, copied into your project and styled to match your design system.
How shadcn-style distribution works
Instead of installing a package that adds to your dependency tree, quiz-ui uses the shadcn registry format. You run a CLI command that copies the component source into your project, under your components directory, where you own the code. The component ships with its own styling layer built on Radix primitives and Tailwind, but since you have the source, you can restyle anything without waiting for a package update.
The registry is built using shadcn's own build CLI, which means it conforms to the native registry schema that shadcn tools already understand. If you are already using shadcn/ui components, quiz-ui fits into the same workflow. The command to add a component looks like any other shadcn add, and the component lands in the same directory structure.
The distribution model matters for quiz funnels specifically because these components need to match your application's design precisely. A third-party widget with its own styles creates visual inconsistency. A component you own and can modify eliminates that problem.
Two layers: headless logic and styled components
The architecture splits into two layers. The core layer under components/ui/quiz/core is headless. It contains the state machine that manages quiz progression, hooks for reading and writing answers, and the branching logic that determines which step comes next. This layer has no styling, no Radix dependency, and no component code. It is pure React logic.
The styled layer builds on top of the core. Each component, QuizRoot, QuizStep, QuizChoiceGroup, QuizNavigation, uses the core hooks and wraps them in Radix-based UI with Tailwind styling. Restyling never touches the branching logic. Extending the branching logic never touches the component code. The separation means you can modify the visual presentation without risking the quiz's behavioral correctness.
This matters because quiz funnels are stateful in ways that are easy to get wrong. A branching quiz has conditional paths, and the state machine needs to handle transitions, answer persistence, and navigation correctly. Keeping that logic headless and separate from presentation means you get the behavioral guarantees without fighting the styling.
Branching is data, not code
A quiz definition in quiz-ui is a plain, serializable JavaScript object. You define the steps, their types, the options for choice steps, and the branching rules that determine which step follows based on the user's answers. The definition can be loaded from a file, fetched from an API, or generated dynamically.
Answer components do not receive value and onChange props. They read and write the current step's answer through a useQuizAnswers hook that the core provides. This means the quiz state is centralized in the state machine, and individual step components do not need to know about the rest of the quiz. Adding a new step type means creating a component that reads its answer through the hook and writes it back. The branching logic and state management stay in the core.
For developers building quiz funnels that need to work across different contexts, web, embedded widgets, email links with query parameters, the serializable definition format means the quiz structure can travel with the data. The same definition works in a Next.js app, a standalone widget, or a server-rendered page where the definition is embedded in the HTML.
What is included
The repository ships with a Next.js site that serves as both documentation and a live example. The example directory contains a complete branching funnel that demonstrates conditional paths, multiple step types, and navigation. The MDX documentation covers the component API, the core hooks, and the registry format.
The components directory contains the source that ships to consumers. The core subdirectory holds the headless engine. The styled components sit alongside it, each in its own file. The registry.json manifest is the source of truth for the shadcn build, and the generated output lives in the public directory.
There is also an llms.txt file that provides an AI-agent-facing index of every component. This is a recent convention in the shadcn ecosystem that lets AI coding assistants understand what components are available and how to use them without reading the source code directly.
What this enables for quiz builders
The practical value is that developers building quiz funnels get a component library that behaves correctly, styles consistently with their application, and distributes without adding to the dependency tree. The branching logic is tested and maintained in one place. The presentation layer is yours to modify. The definition format is portable across rendering contexts.
For teams building lead generation funnels, onboarding flows, or any application that needs multi-step questionnaires with conditional paths, quiz-ui provides the state machine and component primitives without the overhead of a full third-party quiz platform. The MIT license means you can use it commercially without restrictions, and the shadcn-style distribution means you own the code from the moment you add it to your project.