🚀 Executive Summary
TL;DR: This guide provides a step-by-step automated workflow to migrate an entire Roam Research graph to Logseq, addressing the challenge of proprietary data formats. By leveraging a Python script and the `roam-to-logseq` library, users can convert their Roam JSON export into Logseq-compatible Markdown files, ensuring data ownership and saving significant manual effort.
🎯 Key Takeaways
- Roam Research graphs must be exported as a single JSON file for migration.
- The `roam-to-logseq` Python package is essential for parsing Roam JSON and converting it to Logseq-compatible Markdown.
- A Python script is used to define input (Roam JSON path) and output (new Logseq graph directory) paths for the conversion process.
- After conversion, Logseq imports the new graph by selecting the generated local directory via the ‘Open a local directory’ option.
- It is recommended to spot-check complex pages and block references to ensure accurate conversion, although the library handles them well.
Migrate Roam Research graph to Logseq
Hey there, Darian here. As a DevOps engineer, I’m obsessed with data ownership and open formats. I was a heavy Roam Research user for years, but the pull of Logseq’s local-first, plain-text file system was too strong to ignore. The problem? My entire “second brain” was locked in Roam’s proprietary format. Manually migrating thousands of notes was a non-starter, a complete waste of valuable engineering time. So, I automated it. This is the exact, no-fuss workflow I use to migrate a Roam graph, saving you the headache so you can get back to what matters.
Prerequisites
Before we dive in, make sure you have the following ready:
- Your entire Roam Research graph exported as a single JSON file.
- A working Python 3 environment on your machine.
- The Logseq desktop application installed.
The Step-by-Step Guide
Step 1: Export Your Data from Roam Research
First, we need to get your data out of Roam. This is straightforward.
- Log in to your Roam Research graph.
- Click the three-dot menu (…) in the top-right corner.
- Select “Export All” from the dropdown menu.
- In the export dialog, ensure the “Export Format” is set to JSON.
- Click the blue “Export All” button. Save the resulting ZIP file, and extract the JSON file to a memorable location.
Step 2: Prepare Your Local Environment
Now, let’s set up a clean workspace for our conversion script. I always recommend creating a new directory for this kind of one-off project to keep things tidy. I’ll skip the standard `virtualenv` setup steps since you likely have your own workflow for that. The key is to get a clean, activated Python environment running inside your new project folder.
Once your environment is active, you’ll need to install the library that does all the heavy lifting. From your terminal, run the standard pip command to install the `roam-to-logseq` package. This will pull in the necessary code to parse the Roam JSON format and convert it into Logseq-compatible Markdown files.
Step 3: The Python Conversion Script
Create a new file in your project directory named migrate.py. This script will be our engine. It’s simple, defining the input file and the output directory, then calling the conversion function.
Pro Tip: In my production setups, I’d parameterize these paths using command-line arguments or a `config.env` file, but for a one-time migration, hardcoding the paths directly in the script is perfectly fine and much faster.
Here’s the code. Copy and paste this into your migrate.py file:
from pathlib import Path
import roam_to_logseq
import os
# --- CONFIGURE YOUR PATHS HERE ---
# 1. Set the path to the Roam JSON file you exported in Step 1.
# Example for Windows: Path("C:/Users/Darian/Downloads/MyRoamExport.json")
# Example for Mac/Linux: Path("/home/darian/downloads/MyRoamExport.json")
roam_json_path = Path("your-roam-export-file.json")
# 2. Set the path for your new Logseq graph. The script will create this directory.
# This will create a folder named "MyNewLogseqGraph" inside an "output" directory.
logseq_graph_path = Path("output/MyNewLogseqGraph")
# --- END CONFIGURATION ---
def main():
"""
Main function to validate paths and run the conversion.
"""
if not roam_json_path.exists():
print(f"Error: Input file not found at '{roam_json_path}'")
print("Please update the 'roam_json_path' variable in the script.")
return 1 # Using return to indicate an error
# Ensure the parent directory for the output exists
logseq_graph_path.parent.mkdir(parents=True, exist_ok=True)
print(f"Starting conversion from '{roam_json_path}'...")
print(f"Output will be saved to '{logseq_graph_path}'")
# This is the core function from the library that does the work
roam_to_logseq.roam_to_logseq(
roam_json_path,
logseq_graph_path
)
print("\nâś… Success! Your new Logseq graph is ready.")
return 0 # Indicate success
if __name__ == "__main__":
main()
Remember to update the roam_json_path variable to point to your actual file.
Step 4: Run the Script
With your virtual environment still active in your terminal, simply run the script:
python3 migrate.py
The script will print its progress and let you know when it’s finished. Depending on the size of your graph, this could take anywhere from a few seconds to several minutes.
Step 5: Open Your New Graph in Logseq
The final step is to tell Logseq about your new graph.
- Open the Logseq desktop app.
- Click the graph name in the top-left to open the graph switcher, then click “Add new graph”.
- Do not choose “Create a new folder”. Instead, click the button at the bottom that says “Open a local directory”.
- Navigate to and select the
output/MyNewLogseqGraphfolder that our script created.
Logseq will take a moment to index all the new Markdown files. Once it’s done, you’re in! Your Roam notes, pages, and block references should now be available in Logseq.
Common Pitfalls (Where I Usually Mess Up)
- Incorrect File Path: The most common error is a simple typo in the
roam_json_pathvariable. Double-check that the path is correct and that the file actually exists there before running the script. - Large Graph Export: For truly massive Roam graphs (tens of thousands of pages), I’ve seen the browser-based JSON export fail or time out. If this happens, try again during off-peak hours or reach out to Roam support.
- Block Reference Check: The conversion of block references is excellent, but the underlying syntax differs. I always make it a point to spot-check a few of my most complex, heavily-linked pages to ensure all the transclusions and references carried over as expected.
Conclusion
And that’s the whole process. By investing about 15 minutes in this setup, you save yourself countless hours of manual, soul-crushing copy-pasting. You get to keep your hard-earned knowledge while moving to a platform that values data ownership, privacy, and an open, future-proof format. For me, that’s a DevOps principle worth embracing. Welcome to the world of local-first note-taking.
🤖 Frequently Asked Questions
âť“ How do I migrate my Roam Research notes to Logseq using this method?
First, export your Roam Research graph as a JSON file. Then, use a Python script with the `roam-to-logseq` library to convert the JSON into Logseq-compatible Markdown files. Finally, open the resulting output directory as a new local graph in the Logseq desktop application.
âť“ What are the advantages of this automated migration over manual data transfer?
This automated method saves countless hours of manual copy-pasting, especially for large graphs, and ensures data ownership by moving to Logseq’s local-first, plain-text file system, which is an open and future-proof format, unlike Roam’s proprietary system.
âť“ What are common issues encountered during the Roam to Logseq migration process?
Common pitfalls include incorrect `roam_json_path` configuration in the Python script, potential browser timeouts when exporting very large Roam graphs, and the need to spot-check complex block references and transclusions to confirm they carried over as expected in Logseq.
Leave a Reply