Roam plugins by Adam Krivka

Pyroam - Python notebooks in Roam Research

Pyroam - Python notebooks in Roam Research

pyroam gif


To install this plugin, click on the "Copy extension." button below, paste somewhere in your graph and click the "Yes, I know what I'm doing." button.

(Warning: The above method might not work in not Chrome-based browsers, in which case you should follow the manual installation below.)

Manual installation

Copy the following snippet and paste somewhere in your graph.

- {{[[roam/js]]}}
- ``````

It should create a code block. Into the code block, paste the following code:

/** pyroam - Python notebooks in Roam
* Author: Adam Krivka
* Docs:
window.pyroamSettings = {
/** There might some important settings here in the future,
* make sure to check the docs once in a while.
var pyroamID = "pyroam-script";
var oldPyroam = document.getElementById(pyroamID);
if (oldPyroam) oldPyroam.remove();
var pyroam = document.createElement('script');
pyroam.type = "text/javascript"; = pyroamID;
pyroam.src = "";
pyroam.async = true;


The main thing you need to know are the two following keybindings:

<Alt+Enter>Run current cell and write
<Alt+Shift+Enter>Run all cells in active notebook and write

When a codeblock is run, the output is written to the block nested one below it.

The fastest way to add a Python codeblock in Roam is by typing /python and pressing Enter.

Active notebooks

By default, the current page is the active notebook, i.e., when you press <Alt+Shift+Enter>, all blocks on the current page get run and their outputs are written.

You can designate a smaller portion of the page to be the active notebook by referencing the page [[pyroam/notebook]] in the parent block, i.e. all blocks nested under this blocks will get run when pressing <Alt+Shift+Enter>, but no other. You can also nest notebooks - the plugin will always run the "smallest" one.

All variables are shared, it's like if the code blocks were one script.


Currently, numpy, matplotlib and scipy get loaded, though numpy tends to be buggy and plot generation with matplotlib doesn't work yet.

In the future, the plugin will load all imported packages dynamically (as long as pyodide, the underlying Python browser compiler, allows it).

Bug reports & Contributing

You can create issues or pull requests in the repository or DM me on Twitter (

Edit this page on GitHub