🏠 back to Observable

[rant]The current publishing/slug system is a PITA.

Hey there,

The entire notion of “persistence” that observable has is a huge half baked PITA without any real benefits.

  • Slugs are non reusable.
  • Unpublish is limited to 24h.
  • It’s hard and annoying to change notebook urls.

I’d be all in for this kind of “immutable reference” stuff if it was exactly that: immutable.
But notebooks are not immutable, they change a lot, and they can get edited and deleted willy nilly.

This does not solve the problem of code reuse and breakage, it only makes it more annoying to deal with, because it imposes restrictions which in no way alleviate the existing problems, and only create new ones.

Notebooks almost exclusively link to other notebooks latest versions, which is bad and breaks stuff. But it’s the way encouraged by the system, because versioned notebooks are not a first class citizen but an after-thought.
Visit any “@user/notebook@version” url and it will convert into the “d/whateverweirdstuff@version” slug.

The reason why this is so broken is because it complects “user convenient url” with “notebook reuse references”. Those should not be the same thing.
So here’s how it could be:

  • You can choose the notebook url freely, this is just for advertising it to other people (the @user/notebook stuff). Let’s call this the “public URL”.
  • Notebooks also have a “content URL”, which is based on the content of the notebook, just like a git hash. Notebooks are always accessible under that address, unless they are explicitly deleted.
  • When visiting a “public url” a redirect happens to the most recently published “content URL”, making the “content URL” the “real URL” of the notebook.
  • You can unpublish at any time, which will simply remove the “public URL”, but leave the “content URL” intact.
  • You can also delete the notebook, but you will get a modal reminding you that this might break other peoples code, and a list of other options you have that don’t break linkage, like unpublishing.
  • Whenever you import another notebook via a “content URL” the system just leaves it as is.
  • Whenever you import another notebook via a “public URL” the system automatically substitutes the cell with one containing the “content URL”.
  • You can add as much ceremony and tooling around the previous point as you want. “Hey we’ve noticed that your dependencies have updated! Do you want them to point to the latest version?”
  • Profit: No more breaking notebooks, no more annoying slug burning, no more “ah shit I don’t want this on my profile but I don’t want to break other code”, no more “I wish I hadn’t deleted that notebook I’d like to use that slug again”, no more “I really wanna cleanup all this fork mess but the slug is burned”.

Side note: In theory one could push this content addressability into referencing individual cells, but those “code as a graph” approaches, while totally awesome, and a super cool match for observables “code as a reactive graph” philosophy, somehow always fail. Maybe because they are too fine grained for the human mind, with whole “file” and “notebook” versioning being easier to reason about .


Rock on!


Thanks for the feedback, and sorry for the frustration.

Here are some things we’re working on to make this better.

First, proper version pinning for imports (and requires). This will allow notebooks to capture exact versions of imported notebooks and their transitive dependencies, similar to how yarn captures exact versions in a yarn.lock file. This ensures that notebooks keep working into the future: imported code will never change. Internally it will work similar to how you describe: imported notebooks are referenced by id@version (e.g., 09403b146bada149@257 for the current version of @d3/bar-chart).

Second, editable URLs. We’d like to show you what the URL will be before you publish, and give you an opportunity to change it if necessary. And internally we already support changing the URL of a notebook with redirects (e.g., @mbostock/d3-bar-chart redirects to @d3/bar-chart), so we’ll allow you to change the URL after publish, too. (If you want to change the URL of a published notebook in the meantime, please email support. We’d be happy to help!) We’re also thinking about allowing human-readable URLs for private notebooks and for shared notebooks that aren’t listed publicly or discoverable via search.

That said, we’re not planning on letting you re-assign a URL (slug) to a different notebook. Even with version pinning, I think it would be confusing to have a different association between the human-readable name of a notebook and its identity/history (e.g., @​d3/bar-chart@256 meaning something completely different). The human-readable name matters too, and it’s easier to reason about a sequential history than large hexadecimal identifiers (or content hashes). But as an author you can always completely overwrite the content of a notebook as a new version, or trash the old notebook and publish a new notebook at a different URL (slug).