approaches to building a "library" of Observable functions

Hi All,

My team (co-workers but also we do have Teams accounts) wants to build a “library” of functions we frequently use in Observable in order to expedite our work in future notebooks.

My first thought was to have a separate notebook that would serve as our Library notebook, and then we could import functions as needed as one might already do with Jeremy Ashkenas’s Inputs functions, or with Mike Bostock’s Form function.

But I wanted to see if anyone had approached this in a different way that worked well for them. One different idea would be to use JS classes rather than writing individual functions to possibly keep the code cleaner / more organized. Another would be to build something as a JS library and then just import as a module. Would love to hear any pro/cons and/or ideas that people have to share!

Thanks!

1 Like

I use a library notebook that re-exports libraries and useful functions so I don’t need to import them separately and can instead say

import {d3, vl, _, min, max, uniq} from '@yurivish/common'

One downside is that Observable’s code bundling currently bundles together all of the libraries referred to in the common notebook, even if you don’t import any of them:

import {min} from '@yurivish/common'

will still download the code for @vega/vega-lite-api and @jashkenas/inputs, since they are imported within @yurivish/common.

Ah, thank you, the bundling of other imports thing is good to know!

And yeah, a common notebook is what I was thinking about too. Just wanted to inquire about other options before diving in. :slight_smile:

I like individual notebooks with a little documentation and tests ( https://observablehq.com/@tomlarkworthy/reconcile-nanomorph) if I want a bundle for a project it would be a distinct notebook that imported all the others. Did you know you can import another notebooks imports? You don’t need to go to the source notebook which is Handy for bundling. Things slow down with massive notebooks so I try to stay on a single topic.

1 Like

+1 for documentation and testing. I wrote a helper for myself to cover both:

You can find it applied e.g. in the Toolbox and Range Slider.

With library notebooks, version pinning becomes even more important. Unfortunately it’s still fairly cumbersome to find a notebook’s current version. If you need a helper for that, have a look at the Toolbox notebook linked above.

Be careful with additional imports of other notebooks, as the referenced notebooks will be fetched even if they are not part of the dependency chain (because Observable turns them into static imports). I’d also avoid monolithic notebooks and bundle them by topic (preferably) or by frequency (for the most commonly used functions).

2 Likes

Thank you @mootari and @tomlarkworthy. I really appreciate the tips and especially links to your work – I had never seen tests in Observable before!

2 Likes

I love making libraries in Observable. This is a fairly large one: https://observablehq.com/@jflatow/quest, where I started using a new approach to testing in which I uncomment out the testing cell only when I am working on an update.

For your inspiration, here are some other smaller ones:

1 Like