Starter page - interactive diagrams

 from Red Blob Games
14 Apr 2020

I have an interactive tutorial that takes you step by step to make an interactive tutorial in d3.js and another one in vue.js. However, the code for those is more involved than I’d like, so I wanted to make something even simpler. I wrote the same example with several libraries and made some notes for myself. I often use these as a starting point when I’m working on a project.

 1  Vanilla javascript#

No libraries, no build step.

Demo and code[1]


A simpler alternative to createElement etc. is to construct a string and set innerHTML. This is nice unless you have event listeners on those elements. Setting innerHTML creates new elements. If you are dragging the mouse based on an event handler, and the mouse drag replaces the elements, that mouse drag might be running on an element that no longer exists, and that can be tricky to debug. You’ll also have to be careful to escape your HTML correctly if you are setting innerHTML.

 2  Lit-html v1#

Small output library (11k), no build step required.

Demo and code[2]



Haven’t yet investigated Lit v2:

 3  Vue#

Medium sized input&output library (80k), no build step required.



 4  React#

Medium sized input&output library (116k), build step strongly recommended to convert code into regular Javascript.

Demo and code[7] (demo doesn’t use the build step)



 5  Preact + htm#

Small input&output library (10k), no build step needed if also using HTM (2k).

Demo and code[9] (demo doesn’t use the build step)


Preact is like React, but without the tricky items I listed under React: it allows html names like class=… rather than javascript names like className=…; and it allows svg names like fill-opacity=… rather than fillOpacity like React requires. This means you can use an SVG visual editor and export it directly into Preact.

It normally uses JSX like React does but Preact’s HTM is like lit-html’s format, without the tricky items I listed under lit-html: you don’t have to have both html`` and svg``; the templates support xml syntax; and there’s a prebundled version of the library.


 6  Svelte#

Medium sized input&output library, build step required to convert Svelte code into regular Javascript

TODO: demo



 7  ObservableHQ#

Notebook style interface, where top level definitions become reactive in other expressions. Think spreadsheets.

Demo[10] partially implemented ; see source by clicking to the left of any cell.


 8  My thoughts#

The main idea with templates is that instead of writing commands to generate html, we describe the html we want, with some placeholders for values that come from Javascript values. For example:

<rect fill=red x=${col} y=${row} width=1 height=1 />

Compare this to the vanilla approach:

let rect = document.createElementNS("", 'rect");
rect.setAttribute("fill", "red");
rect.setAttribute("x", col);
rect.setAttribute("y", row);
rect.setAttribute("width", 1);
rect.setAttribute("height", 1);

or the d3.js approach:

let rect = svg.append("rect")
              .attr("fill", "red")
              .attr("x", col)
              .attr("y", row)
              .attr("width", 1)
              .attr("height", 1);

I find templates to be a big win. The major libraries in this space (React, Vue, Svelte, Preact, lit-html) all use templates, but the details differ.

<!-- react/preact/vue with jsx -->
<rect fill=red x={col} y={row} width=1 height=1 />
<!-- vue templates -->
<rect fill=red :x="col" :y="row" width=1 height=1 />
<!-- lit-html, and react/preact with htm -->
<rect fill=red x=${col} y=${row} width=1 height=1 />

There’s some difference in how the templates are written. React uses an extension of Javascript called JSX to allow you to write html in your Javascript. You run a compiler to translate that into regular Javascript. Vue reads HTML from your document, or in strings in the source code. Lit-html uses a relatively new feature, Javascript template literals. Preact normally uses JSX but there’s an option to use HTM template literals. Svelte uses its own file format that is compiled into regular Javascript.

In addition, React, Preact, Vue, and Svelte offer a component system that allows you to create custom elements like <GridWorld> that are then expanded into HTML. Lit-html doesn’t do this, and instead leaves that to a separate library, LitElement. For my small projects, the component system doesn’t help me, as I can use regular Javascript functions and classes instead. However, for larger projects, it provides some modularity and also allows you to reuse components that others have written. LitElement uses standard web components that can be used with any other system, whereas React, Preact, Vue, Svelte components can only be used within their own system.[11] shows a comparison of the syntax used across Svelte, React, Vue, and others.

Tricky: in some of these template systems, it is hard to programatically construct the html in certain ways. For example in lit-html the tag name has to be specified statically.

Email me , or tweet @redblobgames, or comment: