# Feature request: Importing Observable module as an Observable notebook.

**URL:** <https://talk.observablehq.com/t/feature-request-importing-observable-module-as-an-observable-notebook/2283>\
**Category:** Uncategorized\
**Created:** [August 19, 2019, 7:05pm UTC](https://talk.observablehq.com/t/feature-request-importing-observable-module-as-an-observable-notebook/2283 "2019-08-19T19:05:35Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![bgchen](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/bgchen/32/784_2.png) [@bgchen](https://talk.observablehq.com/u/bgchen)\
**Post date:** [August 19, 2019, 11:54pm UTC](https://talk.observablehq.com/t/feature-request-importing-observable-module-as-an-observable-notebook/2283/4 "2019-08-19T23:54:54Z")

</div>

Something like what you describe is certainly possible, but it would take some work to put the pieces together.

Suppose you start with a modified notebook JS module and want to upload it to [observablehq.com](http://observablehq.com). [Observablehq.com](http://Observablehq.com) has an internal API it uses for user / notebook data that @mootari has investigated and written some client code for (see [this thread](https://talk.observablehq.com/t/backup-method/1628)).

The API and the Observable editor use a different representation of notebooks, which I’ll call **notebook JSON**. Roughly speaking, these JSON objects consist of some metadata and a field called `nodes` with an array containing cell objects. These cell objects have fields:

- `id`, a unique numerical cell ID,
- `pinned`, a boolean which is `true` if the source of the cell is pinned, and
- `value`, a string containing the contents of the notebook cell.

These notebook JSON objects are “notebooks as data” and JS modules are “notebooks as code”. Therefore, transforming from one to the other is a type of compilation / decompilation. I investigated this a while back for the **V1** runtime format (inspired by [this notebook by @asg017](https://observablehq.com/d/5720deb83ebe0fc6) on the Observable parser) in the following pair of notebooks:

- [This notebook](https://observablehq.com/@bryangingechen/from-raw-notebook-source-to-observable-runtime-v1-modules) contains a function that compiles notebook JSON to a runtime V1 module.
- [This notebook](https://observablehq.com/@bryangingechen/fromv1) has a function that decompiles a runtime V1 module to notebook JSON (with some limitations).

Thus, returning to the scenario where you have a modified notebook JS module file, you first need to “decompile” it to a notebook JSON file (using something like the `fromV1` notebook above but for the V3 runtime).

Once you had that, you could then try using [this nodejs script](https://gist.github.com/bryangingechen/9d86f1e5ec01674a32dd9c54bdc13947) from the above forum thread to upload the notebook JSON as a new notebook. Then you could merge the new notebook into your already-existing notebook. The script could probably be adapted to do these last few steps automatically for you.

Note that I haven’t used this script in months so I’m not sure if it still works. (It would probably be better to rewrite it using @mootari’s [observable-client](https://github.com/mootari/observable-client) library.)

As you can see I’m quite interested in offline tools for Observable notebooks as well. Given more time and energy I’d want to clean up the bits and pieces above and then put some effort into an Observable notebook VS code extension…

---

_[View the full topic](https://talk.observablehq.com/t/feature-request-importing-observable-module-as-an-observable-notebook/2283)._
