Javascript user interfaces
November 11, 2014 — January 11, 2024
Leverage JavaScript’s ubiquity, brainshare, and tooling to build user interfaces. My target audience with this notebook is people like myself who are not UX professionals but want to bang out a quick interface for some minimum viable project, which can be handed off to an actual professional once the glitzy animations and oversaturated colour scheme have charmed the boss into allocating resources.
JavaScript is an emergent weapon of choice for interactive visualisation. If that is what you are doing, maybe try starting with the limited but ultra-simple dat.gui; fall back to the more complicated options listed here as needed. Note that there is a primitive JS UI built into Jupyter, by the way, if you simply wanted to control a scientific browser visualisation. See Jupyter UI.
1 dat.gui
dat.gui is the simplest option. It is designed for tech demos and such where the main user interface option is a slider widget. Use it if you can, because everything else is much more complex. On the other hand, if you are really, truly sure in your heart of hearts that you are starting off a big project that is intrinsically more messy than a fixed set of sliders and numerical widgets, do not use this. Use some over-engineered alternative and resign yourself to much more wasted time getting to the payoff of a usable interface in exchange for future flexibility. The docs could be clearer; try David Walsh’s excellent tutorial. Not quite sophisticated enough? Maybe progressive-enhancement style is what you want.
2 JQuery et al: the progressive enhancement ecosystem
Before there were JavaScript app frameworks, people used JavaScript to add interaction to HTML. If the page structure is not too dynamic, this is vastly simpler than the FRP style because there is no complicated app-building stage needed, and you are rather close to the original vision of the web rather than the modern web-app. This has both pluses and minuses.
- handy, hoary, mullet (as in “business in front, party out back… omg they are huffing cream bulbs”) user interface library: jQueryUI. Classic, not great for touch devices though.
simulus is a JavaScript framework with modest ambitions. It doesn’t seek to take over your entire front-end—in fact, it’s not concerned with rendering HTML at all. Instead, it’s designed to augment your HTML with just enough behaviour to make it shine. Stimulus pairs beautifully with Turbolinks to provide a complete solution for fast, compelling applications with minimal effort.
3 augmented HTML
Modern browsers have predictable extensibility in HTML, which can be used for relatively simple upgrades, e.g.
possibly best illustrated by ///_hyperscript examples.
4 FRP style interfaces
One useful trick for me was/is plugging into functional reactive style for handling user interfaces meshing with other streams of data. The popularity contest winner is React, but there are other contestants. React seems to be effective enough to get people enthused, but then chaotic and messy enough in practice that people inevitably rewrite it with slightly different pain points. There are many variants, all annoying in different ways, so I guess converging upon React, which at least has longevity, is not too stupid?
That said, people make cases that more modern solutions are better. Josh Collinsworth’s Things you forgot (or never knew) because of React seems to me to collect the most useful stuff in one place.
Thought: Would it be superior these days to ditch JavaScript and use Dart to build a Flutter interface?
preact is a light version of React, which is a good idea. Because if nothing else, the build time of React is boringly slow. Preact comes with an instant project builder.
One thing that looks usefully different for my purposes is Svelte. This JavaScript framework offers some conceptual similarities to React, but it compiles to an optimised minimal version. Compiling JavaScript to JavaScript which is in turn compiled again is obviously absurd. Except that the various JavaScript app bundling frameworks do a giant code analysis and mangling step anyway, so you may as well do something useful while sitting around accruing that overhead. I am curious how awful that is to debug.
4.1 React
The modern default for JavaScript UI is to use React, which If you’re going to use JavaScript, you may as well go deep and use a UI system radically redesigned from the ground up to use its strengths. React is a classic contender here, the archetypal one, and its approach has come to dominate the JavaScript ecosystem. See also, e.g. the many alternative work-alikes such as riot, which look similar but lighter. There are certain philosophical entailments to this system, as opposed to the conservative Model-View-Controller viewpoint, which attract more pontificating.
- resource Wiki.
- react devtools gives you a browser debugger for Chrome or Firefox.
- create-react-app streamlines app building.
4.1.1 State management
FRP makes things look elegant, but in practice, there are many horrible complexities that arise if you are not writing a TODO list app, which is what they all seem optimised for. For complicated scenarios, one is well advised to choose a state management library.
Comparison of some React State Management libraries by features is a good place to start when choosing, or inspecting popularity of said libraries on NPM.
I used Redux a lot. It was not great for me, in my app that did lots of weird stuff with sensor data, but it is probably good for TODO lists?
- Redux - A predictable state container for JavaScript apps. | Redux
- reduxjs/redux: Predictable state container for JavaScript apps
- Redux Toolkit | Redux Toolkit
- @reduxjs/toolkit - npm
Another popular one is Zustand:
I have not used it.
4.2 Observablejs
There is a parallel universe system called observablejs which combines some features of FRP and some of JavaScript visualisation and UI.
5 Vue/Angular etc: The 2-way binding ecosystem
Vue exemplifies (or exemplified? I have been told they changed the system in Vue 3?) a slightly different approach to the FRP style. Instead of immutable-esque state streams, something about two-way binding? Have not tried myself. AFAICT the whole paradigm is being gradually out-competed by the FRP-style one.
VueJs according to Wikipedia…
was created by Evan You after working for Google on AngularJS. He later summed up his thought process, “I figured, what if I could just extract the part that I really liked about Angular and build something really lightweight without all the extra concepts involved?”
6 HTML-first ecosystems
The Grug Brained Developer wrote a system that attempts to treat the web as a hyper-card-like system, and it somehow precipitates an alternative JS UI from some different paradigm?
It leads to this kind of pattern:
7 Performance concerns
- Measure Performance with the RAIL Model
- Chrome has draconian policies for scheduling on slower computers and tablets — e.g. expensive task blocking scheduling logic, leading to lots of violation warnings if you use the scheduler. Google’s policy is that you need to do React updates in a webworker or in “micro partial updates” broken across several
requestAnimationFrame
updates — see Optimize JavaScript Execution. - Moving Atom To React, including seeing GPU usage and the
translate3d
trick for shunting to the GPU. - Scrolling Performance.
- debouncing for good animation performance.
- Jank busting for better rendering performance.
- 9 things every React.js beginner should know.
8 Widgets
Storybook.js is an IDE for web components.
Knobs? Try the handy SVG jimknopf. (I don’t believe it handles multitouch though)
jquery knob is not ugly, but not very fast or modern. Good for one-offs.
NexusUI offers a toolkit for musical/VJ controllers, including bridges to OpenSoundControl. But using canvas, for some godawful reason, which misses one of the strong points of browser interfaces - 20 years of developing a good interaction model.
-
allows Nexus UI control surfaces to be constructed via OSC without the hassle of writing any JavaScript or HTML.
-
is similar to NexusUI, but quirkier and about a year older, so has vanished from our goldfish collective memory. Also, Charlie Roberts’ code is powerful, brilliant even, but his highly opinionated aesthetic rubs me the wrong way so I don’t enjoy it.
-
tangible.js lists some further useful libraries for this purpose.
And endlessly more widgets! You can get more widgets using Web components.
9 Web components
Web components which, thanks to projects like polymer, give you shinyshiny knobs, buttons and HUDs from plain old HTML.
Web Components usher in a new era of web development based on encapsulated and interoperable custom elements that extend HTML itself. Built atop these new standards, Polymer makes it easier and faster to create anything from a button to a complete application across desktop, mobile, and beyond.
Powerful. Flexible. Almost certainly too complicated for what I want. Intrinsically complicated, even if browsers were all the same, but they are not, so you have to venture into an even more complicated world of “polyfills” and sensitive version dependencies to use them.
Do you really need to go there? Are you sure you don’t want to hire a user interface professional to deal with that bit? OK, I can’t stop you.
See this plain-talk web components howto or welcome to polymer, or Polymer code or PolymerLabs code or other things I am too unspeakably bored to countenance.
10 Icons
See vector icons.
11 Offline JS apps
See JavaScript apps?
12 Multitouch
Is tedious to debug because most desktop machines don’t yet support it.
Multitouch browser patch is one workaround. I’ve been using touch-emulator, which is adequate so long as I use a build tool to prevent me from accidentally deploying it in production.