Lightweight. TypeScript-first. Fully headless.
Build accessible, schema-driven surveys in minutes — not days.
Why Choose This Library
Start with zero config, stay headless, plug in your own design system, and ship accessible surveys without the bloat.
~13 KB gzipped for the full renderer, ~4–5 KB for headless core only. Zero heavy dependencies. Tree-shakable entry points.
Full control over rendering. Bring your own UI or use the built-in components.
Visual survey builder with drag-and-drop reordering, live preview, and JSON editor.
Complete type safety from schema definition to answer handling. Full IntelliSense support.
Built-in pagination with progress tracking, navigation, and per-page validation.
Rich validation rules: required, min/max, patterns, email, and custom validators.
Override any question component. Register custom question types via the plugin system.
Show or hide questions and pages based on user answers with expressive condition syntax.
All form fields are fully WCAG 2.1 compliant with proper ARIA labels, roles, keyboard navigation, and focus management.
First-class support for Next.js and server-side rendering. Works in App Router and Pages Router without any extra configuration.
Define entire surveys as plain JSON. Version control them, generate them programmatically, or load them from an API at runtime.
Built-in state management via the useSurvey hook. No Redux, Zustand, or external store required — answers, errors, and page state just work.
Developer Experience
Define your survey as a JSON schema, then render it with the built-in components or go fully headless.
import { useSurvey, SurveySchema } from 'react-minimal-survey-builder';
const schema: SurveySchema = {
id: 'feedback',
title: 'Customer Feedback',
pages: [{
id: 'page1',
questions: [
{
id: 'name',
type: 'text',
label: 'Your Name',
required: true,
},
{
id: 'rating',
type: 'rating',
label: 'How would you rate us?',
},
{
id: 'feedback',
type: 'textarea',
label: 'Any additional feedback?',
visibleIf: '{rating} <= 3',
},
],
}],
};
function FeedbackForm() {
const survey = useSurvey(schema, {
onSubmit: (answers) => console.log(answers),
});
return (
<form onSubmit={(e) => { e.preventDefault(); survey.submit(); }}>
{survey.getVisibleQuestions().map((q) => (
<div key={q.id}>
<label>{q.label}</label>
<input
value={survey.answers[q.id] ?? ''}
onChange={(e) => survey.setAnswer(q.id, e.target.value)}
/>
{survey.getError(q.id) && (
<span className="error">{survey.getError(q.id)}</span>
)}
</div>
))}
<button type="submit">Submit</button>
</form>
);
}How We Compare
See how this library stacks up against heavyweight alternatives.
| Feature | Ours | SurveyJS |
|---|---|---|
| Bundle Size | Lightweight (~13KB gzip) | Heavy (200KB+) |
| Headless Mode | Partial | |
| Drag & Drop | Yes | |
| TypeScript | Partial | |
| Custom UI | Easy | Hard |
| React Hook | ||
| Zero Config | ||
| Plugin System | Yes | |
| WCAG Compliance | Partial |
Community
“Finally, a survey library that doesn't try to own my entire UI. The headless hook pattern is brilliant.”
“Migrated from SurveyJS and cut our bundle size by 80%. The TypeScript types are chef's kiss.”
“The drag & drop builder saved us weeks of development. Shipped our survey feature in 2 days.”
Start for free. Zero dependencies. Headless by design. Fully customizable from day one.