Observable-driven Open Survey Application

Hi Community!

I’d like to share a survey application built on Observable (with an AWS back-end). @tomlarkworthy built it and @saneef led the design work. My contribution was mainly in motivating the project but since I also control the team account and just published everything, please allow me to share:

Let’s encourage Tom to write some words about the project (as he’s been planning to do, but I’ve been slow to publish).

Thank you to everyone for making this possible! Please review, comment, fork and share! We’d like to see this work adopted, extended, and advanced.



Hi, the main survey filler notebook has been published so you can see what all those other notebook were building towards!

It provides magic link access to a custom survey response application. Data is persisted to AWS S3 and isolation is enforced via IAM. Each question is a vanilla Observable input cell, but they are all squished together hierarchically into a single cell which can then be easily deployed to s3 and white labelled.

The designer notebook is a UI used for designing these custom surveys, the admin notebook is about provisioning users and deploying the white label version.

I will write a blog post about the project, but it will be quite big so it might take a while to be released. The project heavily utilizes the view literal and the workflows explained in Scaling User Interface Development). The broad principles of the development are

  1. An application is a single viewof cell, but you build it piece-by-piece hierarchically. You should have interactive demos at every level of the hierarchy. You can see the backing UI heirarchical development notebooks in Survey Slate | Survey Components / categori.se / Observable

  2. Business logic is not placed in UI components! They are given state controls like “visibility” which reactively do the obvious DOM manipulations. These UI control fields are back-writable! A UI component is a viewof with affordances that make sense in the UI domain.

  3. Business logic is added in external cells, which are connected to the UI via Input.bind (or similar). Often business logic has a different set of affordances so they needs to be a mapping in and out of the UI cell.

  4. As soon as you have features like auto-save on change, and auto-load on first page visit, you end up reading and writing to the main UI component in complex ways. So you need component backwritability, and you need to be programmatically invoking dataflow via arbitrary logic. You will not be able to put your dataflow in a DAG, there will be loops, and as a result, you will need to use viewof because they offer more control flow expressivity (this is covered in the Scaling UI development notebooks too). I tried to extract some of table stakes building block control flow patterns in patterns / Tom Larkworthy / Observable but be warned auto-save is another level of difficulty entirely.

Problems: The view-literal was essential to this application, but we have discovered some scaling issues. At the moment it synchronously builds all DOM elements. In the case of the designer UI this can be 100k views which can cause the page to freeze for >10 seconds. Once its loaded you can Input.bind granuarly to subtrees, so its ok once loaded. Other UI frameworks like React and friends solved this issue with deferred rendering, and on close inspection of the view-literal API we could add this feature without an API change (because dynamic arrays are passed an element builder rather than pre-build elements), however, we ran out of time to add that feature and as it does not affect the core filler application this remains an open issue for very complex UIs.

Hope it helps!