Hacker News new | ask | show | jobs
by simonw 562 days ago
I've been playing around with the idea of alert() and prompt() and confirm() replacements that work like this:

    await Prompts.alert("This is an alert message!");
    const resultBoolean = await Prompts.confirm("Do you want to proceed?");
    const name = await Prompts.prompt("What is your name?");
Demo here: https://tools.simonwillison.net/prompts-js - code written by o1: https://chatgpt.com/share/67539c28-4df0-8006-b021-4f468e011f...
4 comments

For a company that had a giant 30 minute wizard in the web interface, I wrote a wizard engine in VueJS that works similarly. It's served hundreds of thousands of users since 2019 and went through medical device certification :) Took me quite some time to realize we can use `await` to wait for user input too, not just APIs etc.

I recently re-created parts of it from memory for a hobby project and just now open-sourced it: https://github.com/jtwaleson/wizard-engine

The neat thing is that we can program the complex logic of the wizard with the full power of the programming language. By making each screen in the wizard a function that has input parameters and a return value, we can treat it like any other function. Show the same screen 3x in a row? Use a for loop. Show a screen with input that depends on the output of the previous step? Just use a variable to store the results.

Why is it any surprise that one can use await to wait for user input? It is just promises under the hood, right? So that is exactly like one would expect a promise using dialog to work.
I found that non-obvious too: in both Python and JavaScript I've always seen "await ..." as effectively a hack to enable concurrent execution via an event loop, where the hope is that you won't be waiting very long at all for a response.

Realizing that you could use it for user input - where your promise might not resolve for minutes or even hours - was a bit of a light bulb moment for me.

Indeed, just me being stupid for realizing it so late. Coming from Java and Python 2 I never really understood async/await properly and when I started to grasp it, it took me weeks to realize I could apply it to user interactions too.
I don't think I've ever seen an example of it used that way in any tutorial, blog, or project documentation ever.
I improved this (by porting it to the dialog.showModal() API, relevant to this post) and shipped it to NPM as a package called prompts-js.

Code here: https://github.com/simonw/prompts-js

Blog writeup: https://simonwillison.net/2024/Dec/7/prompts-js/

Seeing ChatGPT use `return new Promise(...` directly inside an `async function` makes me somewhat less apprehensive about the future.
While they are nice, they don't block the event loop. That's definitely a feature you would need if you're aiming to replace `alert` and friends. As an alternative, yeah, that's a pretty reasonable API.