Source control & Observable

I’m loving Observable for as a notebook for learning & exploring new datasets. The ease of use of the exsisting JS ecosystem within Observable is fantastic, and has saved me a lot of time.

However I am struggling with the other direction, and looking for a solution to move notebooks back into my JS ecosystem (or into production). I find myself copying code out of a notebook, going back to poke at the notebook again, copying local changes back in, and vice-versa.

Ideally I’d love a mechanism to share code in a more bi-directional manner with an Observable notebook and local projects living in source control.

Has anyone else been thinking about this, or maybe has found a solution? Or, is my workflow broken?

-Carl

I continue to dream about a read/write API for notebooks, so that people can use whatever external tools (source control, text editors, …) they prefer.

For now I think copy/paste is the best you can do if you want to get content into Observable notebooks, unless you want to use some kind of hacky pretend-to-be-a-browser method.

I just asked for this over the weekend: API Request as I am working on a VSCode Observable extension (see pics in API Request)

@GordonSmith got it! I’ve been noodling with essentially the same concept for local dev.

This is an important topic: Unlocking Observable notebooks so that they can serve as components of larger projects and work together with production applications is something we’re very interested in making easier.

It would be extremely helpful if you could describe a little more about your particular use case. For example: Are you running individual cells as components within a web application? Using React? Or are the cells running server-side? Are you using the Runtime to run cells reactively, or avoiding it (as in the notebook distiller)? Or is this more a matter of providing a more convenient API so you can sync down your notebook source code into a local git repo on a regular basis?

3 Likes

@jashkenas I don’t think I want an API (can’t believe I just typed that).

My primary use-case is publishing a notebook or a subset of cells in a designed format to a website or application. I am using the Runtime to run cells reactively (notebook distiller tho :open_mouth:). No trouble pulling down the notebook or using the Runtime. But iteration from there was tedius; it felt like write once.

Secondary use-case is as an author (this is aesthetic, but maybe helps with the above). Lack of annotated history has tripped me up a couple times in Observable itself. The web UI is beautiful, and incredibly powerful for getting oriented in a new problem. But after orientation, in telling that problem’s story (or in particular stories) I want to refactor, extract things, share functionality. This feels more awkward and a lot more fragile than the honeymoon I just had with the problem when it was new.

Conceptually I’m looking to move seamlessly between a notebook and local code, which I can refactor into from the notebook. The ideas from the VS plugin are compelling (API Request - #4 by bgchen). I think any local notebook environment would get me a lot closer. Browser livereload & the runtime sounds complicated. Admittedly, this isn’t very concrete — I’m not even sure what text I would be editing, and with what.

I’ll be tinkering with it irregardless, but really appreciate your thoughts!

Just to check, have you tried — instead of downloading a copy of the notebook as a tarball and installing it locally — just loading the latest version on ObservableHQ.com from your code by URL instead?

Then you should be able to just refresh the page (perhaps after pressing “publish”, or “reshare”), and get the latest version of the notebook right away.

The general pattern is: https://api.observablehq.com/@USER/SLUG.js?v=3 … and if you want to load a private notebook, you can do that too, with an API key.

This is helpful, thank you!

I glossed over that early on in one of the embedding notebooks or maybe the Runtime docs. It won’t quite solve for the bi-direction workflow but at a glance I think I can work with this in my primary use-case.