How to import Roam backup into Obsidian while preserving block-level references/links?

As far as I can see, when you export a Roam graph in Markdown format, links to blocks are not preserved. Links to pages show up as [[name]] and are imported correctly but references to blocks don’t show up in any way. It would seem that block-level links/references are not preserved in any way when exporting to Markdown.

However, it seems like when you export to their (new?) high-fidelity EDN format, everything about your graph is preserved, including block backlinks. (See also this similar issue [Export/Import] Block-Level Back-References Are Not Preserved · Issue #451 · Roam-Research/issues · GitHub ).

So - I assume in theory it’s possible to import an EDN file into Obsidian in a way that preserves block-level links. Just wondering if anyone knows of a tool to do this?


I assume that Roam has no public documentation for its EDN format.

They’re explicitly admittedly that their earlier markdown and json exports were only partial. Which isn’t good news for anyone who has paid to lock a lot of their data into Roam. They’re also suggesting that they couldn’t find a way to export the total data into json (that surprised me a bit, but I’m not an expert); markdown I understand because it doesn’t have any native way of dealing with blocks. Or backlinks.

I’m sure that someone who understood the EDN format could produce a better set of Obsidian compatible markdown files, but there might still be some features that don’t align.

1 Like

The EDN format seems understandable if you open it up in a text editor, although very cumbersome.

The JSON format preserves enough for my liking - it does preserve the block references (I tried importing it into Logseq) but it does not keep the back-links from a referenced block, which I can live without. Is there a way to import the JSON into Obsidian?

Edit: the above is incorrect - the JSON does seem to keep back-links from a referenced block when it’s imported into, for example, Logseq. That is, the github issue I linked above does not apply when the JSON is imported into a non-Roam service.

1 Like

Someone would still have to write a converter into Obsidian markdown.

I don’t know who wrote the current Roam importer, but I think that just works from the exported markdown?

I’m sure someone will do one sometime to include block references. (If it’s Licat, I hope mobile and sync come first.)

I amended my post above: when I import the JSON into Logseq, it also preserves the count of back-links from a referenced block. So the github issue above is not reproduced when importing the JSON into a non-Roam service, which means the JSON should have all the info needed?

The current importer works from the markdown, but the markdown as exported from Roam doesn’t include any details about block links. Therefore it would be impossible to write a markdown importer that keeps this info, any importer would have to deal with the JSON (or the EDN).

Fingers crossed then :slight_smile:

@BigHead my suggestion would be to add a request in #plugins giving as much information as you can about the EDN format (maybe an example would be nice or where to get a sample file). Perhaps another ex-roam user (or someone who uses both roam and obsidian) can help out, but if not another plugin developer might need all that info before they consider volunteering their time.


Thank you, I did that at Import Roam backups in JSON or EDN format, so that block-level links/references are preserved !

I just stumbled across this post. I wrote a Roam JSON to Obsidian converter that preserves block references (inserts ^blockids and links to them). It’s available here:

It’s not very polished yet but it did the job of making my Roam JSON export usable in Obsidian, especially when followed by Obsidian’s Markdown importer cleanup.

Hope this helps.


If you haven’t already I would post this also in the original thread: Some thoughts on using Roam as an Obsidian person / Questions for Roam Refugees and would definitely make a post in #share-showcase

1 Like

Yeah, great, please do so! I am totally new to the forum and don’t know my around yet.
(Don’t I know you? From my times maybe?)

If you like, you can also link to my post about why I switched if that is of interest.

Thanks a lot for helping out! This is really a great, supportive community :clap:

1 Like

These might be useful

There hasn’t been any activity for 5 days, could you please see if you’d like to pick any of the existing answers as the solution, or do you still need help with something?

Would appreciate it if you could clarify on that, thanks!

Thank you for creating this. I’m not a coder but I’d like to try to use this. I now have Python installed on my Windows PC but can’t figure out how to get this to run from the command line. I’m used to pasting JS code blocks into Roam but don’t understand how to make this function. I’m new to Obsidian as well - does the code run in Obsidian or does your Python code prompt for an input/upload of the Roam JSON export?

Thank you @renerocksai for creating this script for us!
I got an error and posted an issue for you on Github. It looks like Anwesh has submitted a pull request that will fix the error and make other improvements. Can you take a look?