Forms are just code, so I wrote them that way.
FieldCraft is a schema-driven form engine for React. You describe a form once in JSON and it handles validation, conditional logic, multi-step navigation, drafts and submission.
I built it to learn how to publish and maintain npm packages. It works, I use it, and the source is MIT if it’s useful to you.
I wanted to see how a package of mine holds up once it’s published.
So I picked something big enough to find out: a form engine. Forms have enough real problems — validation, branching, steps, drafts, submission — that you can’t fake your way through them.
Somewhere in the middle I stopped writing things down. Coming back to it now, I spend more time relearning my own code than adding to it, which is why fixes and features have slowed. This page is part of fixing that.
If you’re here from a CV or a link: the interesting part isn’t the marketing, it’s the code, the tests, and the parts I got wrong. Those are all in the repo.
Read the source →Three steps, and no account anywhere.
Easier to show than to explain.
Four behaviours the engine handles for you, running here on this page: steps, conditional fields, validation and computed values.
Sections become steps. Progress, forward and back navigation are built in. Each step can declare its own showIf condition so the flow adapts to previous answers.
Contact
Two layers, four packages.
The engine is plain TypeScript with no UI dependencies. The React renderer sits on top of it and adds the field components. Install whichever one you need.
Things you should know before you rely on it.
I’d rather you find these here than three days into a project.
Mostly that shipping is the hard part.
The engine was the fun bit. Everything around it is where the actual lessons were.
A scoped npm org, four packages that depend on each other, build outputs that work in both ESM and CJS, and versions that don’t contradict one another. None of that is writing features.
1,151 tests weren’t for correctness so much as for me — they’re the only reason I can still change the engine after forgetting how it works.
Checking the schema at boot instead of trusting it at runtime removed a whole category of confusing bugs. Obvious afterwards; wasn’t obvious to me at the start.
The main thing I’d do differently. Undocumented decisions cost me more time than any bug did.
Or start from one of these.
Schemas I wrote for real forms, cleaned up. Copy one, change the fields, render it.
Contact Form
A two-step contact form with personal details and inquiry fields. Includes name, email, phone, subject dropdown, and message.
Feedback Survey
A comprehensive customer feedback survey with NPS, ratings, Likert scales, feature usage tracking, and conditional follow-up. Three sections covering satisfaction, specifics, and open-ended feedback.
Job Application
A comprehensive 3-section job application form with personal info, position preferences (role, type, salary, remote), experience details, cover letter, and consent.
Where it stands right now.
Install it, write a schema, render a form.
Nothing to sign up for. It’s on npm, the source is on GitHub, and the licence is MIT.