Hello HN!<p>A little over a month ago (`git log` says Nov 8) I was looking for a way to add a contact form to a different side project that was just a static landing page at the time. I went looking for form-builder tools, but disappointingly, almost every single one I found had (frankly egregious in many cases) per-submission pricing. In fact I only found one tool[0] with sane limits suitable for a side project like this, but I was a bit put off by its Notion-esque interface. To be clear: the tool is great, it's just not a great fit for me.<p>In any case, this led me to want to build something along the lines of a "form-builder for hackers", which would let me build forms quickly and without fuss, preferably from the command line, preferably using a plaintext interface. I didn't want to use a half-baked custom DSL to define forms, and using a real programming language seemed like a safer starting point. Things really started coming together once this decision was made. If you're using code to define a form's questions, it's a small step up to use code for form logic, styling, and so on.<p>Well that's what Formulate is – a form-builder where you create forms with code. I worked on this in my spare time over the last month, and I'm pretty happy with the results so far. You can't use it from the command-line yet[1], but here's the general idea:<p><pre><code> 1. A form is a Javascript file that executes in the respondent's browser (it's sandboxed)
2. Formulate gives your code a `form` global that lets you present questions to the user, make HTTP calls, etc.
3. Your code can't access `window` or `document` but is otherwise a regular JS execution environment
4. Answers to all questions are saved automatically when the respondent makes it to the end
</code></pre>
I'm particularly happy with the way undo[2] has turned out, which works by replaying your JS file from the top with all sources of non-determinism (including previous answers) cached in local storage. This _effectively_ gives you the ability to rewind code[3], but the implementation cheats by starting from scratch every time.<p>I hope you enjoy playing with it! Given the amount of time I've spent on this so far, there are bound to be features missing and bugs lurking. Let me know if you see anything weird or particularly annoying so I can fix it for you.<p>Finally, a couple of links:<p><pre><code> - Documentation: https://formulate.dev/docs
- Ask questions (or get help): https://discuss.formulate.dev
- Landing page: https://formulate.dev
[0]: https://tally.so
[1]: https://discuss.formulate.dev/t/command-line-interface-for-formulate-dev
[2]: https://formulate.dev/docs/advanced/undo
[3]: https://en.wikipedia.org/wiki/Time_travel_debugging</code></pre>