Observable Notebooks 2.0 is here! And my first impression is… it’s good.
More important than anything I have to say about it, the notebook you’re currently reading is my first attempt to publish a notebook to my website. I’m quite happy with the result. 🎉🍾🥳
Let’s back up. I’ve been a strong believer in Observable notebooks since the public beta launched in 2018. It’s the coding environment I always wanted but had not myself managed to will into existence. Reactive cell evaluation conforms easily to my mental model of how code should run, and Observable’s editor UI/UX and product execution has always been top-notch. Observable Plot is wonderful. I have about 520 private notebooks, about about sixty of which are somewhat presentable.
Of course Observable isn’t perfect. Observable-flavored JavaScript isn’t for everyone. JavaScript libraries to power numerical analysis have always been underpowered. The vertically-tall notebook format doesn’t perfectly fit horizontally-wide screens. And “Please allow us to edit notebooks outside of Observable” has been a long-running feature request.
Finally, and perhaps most importantly, I’ve always been uneasy about ceding control of my work to a private company. From everything I can see as an outsider, they’re wonderful people making wonderful products. Still, sometimes I’d like to poke around at medical, legal, or propietary data, and even for casual notebooks, it’s a roll of the dice to fully trust that notebooks I create today will be here tomorrow.
They haven’t suddenly solved everything, but when I saw the Observable Desktop and Observable Notebook Kit product announcements, it was quickly clear they’d done something meaningful and done it well.
I mean, this is it, right? An offline editor application whose output is a human-readable HTML file. What else is there? Notebooks are now just a few lines of code. The interface works offline and if you install a lightweight dev server, you can sidestep the app in favor of a text editor and a web browser.
notebook theme="air">
<title>Hello, Observable Notebooks 2.0!</title>
<script id="1" type="text/markdown">
# Hello, Observable Notebooks 2.0!
</script>
...
</notebook>
<
There’s no sense talking this to death. You should go try the app!
The second new component is Notebook Kit. There’s a bit more to understand here. There are different library components—vite, build, utility, and runtime—and I’ve only scratched the surface.
As far as the coding experience goes, there are some subtle differences. In addition to Observable JavaScript, you can now code in plain old JavaScript. It took me a bit of experimentation to understand how this plays with reactive cell evaluation.
Recall that with Observable JavaScript, each cell has a single output. What we may previously have written as a bare and block statements x1
and y1
, respectively,
x1 = y1 + 5
y1 = { return r; }
we now write as plain old JavaScript,
const y2 = r;
const x2 = y2 + y2;
display(x1);
display(y2);
From what I can tell, it still processes top-level variables of .js
cells in cell-wise topologically-sorted execution order; it’s just that it now permits such variables as plain old JavaScript with multiple outputs.
And as always, this is still Observable, so it’s all running live and has access to lovely libraries like Observable Inputs. You just need to swap out viewof
with view()
.
const r = view(Inputs.range([1, 10], {step: 1, label: 'r'}))
There do appear to be a few missing features, though of course that’s to be expected since it’s billed as a technology preview. For example, pulling in Observable notebook cells with import
works great. But importing a viewof
does not.
Update: Mike Bostock has provided some assistance and gently nudged me toward JavaScript rather than Observable JavaScript as the path forward. I’ve updated the code below correspondingly.
We’ll test out imports by importing a figure from my notebook Drawing 3D Objects with SVG. It seems that "viewof$*"
in JavaScript is interchangeable with "viewof *"
in Observable JavaScript, and with that, we’re back up and running.
import { figure, viewof$rotation } from 'observable:@rreusser/drawing-3d-objects-with-svg'
figure
viewof$rotation
The real moment of truth for me though was discovering what it means to integrate this into my personal website.
Overall, the story is quite good. It uses the wonderful Vite tooling to produce static output. Multiple pages are easy to set up. And you can provide a HTML template to wrap content. I accomplished most of this with some light vite configuration, which you can find here.
I also ended up slightly modifying @observablehq/notebook-kit so that I could pull notebook metadata into the surrounding template via a transformTemplate
function I added. You can find my changes here, which I’ve submitted as a PR, though I do suspect there are probably better ways to accomplish this.
I’ve always been a fan of Observable, but with this new tooling, it feels like we’ve sort of arrived. I always wanted sort of a combo blogging platform slash notebook development environment, and for the first time ever, it’s sort of just unfolded in front of me without any major obstacles.