Migrating from Notion to Obsidian
8 min read
Recently, I’ve been getting rather frustrated with the state of my general purpose note-taking, and thus, stopped creating notes altogether, unless I absolutely HAD to create them. The reasons for this displeasure were simple: Notion, the service I was still using as my go-to is still not using properly formatted plain Markdown documents, so exporting is as painful as ever, and privacy is still something they don’t really talk about in detail (especially, end-to-end encryption).
I knew I would have to create a lot of notes in the coming weeks and months to finish writing my Master’s Thesis, so I needed a reliable way to keep track of various bits and bobs of knowledge - and I needed it to be quick and simple, so I would actually do it instead of putting it off. After looking at Obsidian very briefly, I really liked (and still do) the fact that notes are still based on pure Markdown, and I can read it with any other program at my own discretion. That means, no proprietary format to lock me in, and no weird exporting process I’d have to go through to extract my notes from this tool, and thus - I’d decided I wanted to try it out.
First Steps in Obsidian
I’m quite familiar with the concept of editing basic notes and basic files in Markdown, and I’ve written a few Markdown documents for various Git repositories, so I felt right at home in the UI. Writing notes is easy, structure and organization is clear, and the command palette makes the UI easy to navigate without a keyboard. The inclusion of a VIM-Mode plugin is the icing on the cake. I’m convinced at some point I might even remember the order of parentheses for creating links (it’s [Text](Link), in case you’re curious).
Core and Community Plugins enhance the usefulness of Obsidian by hooking into tools and concepts I’d already used elsewhere, like an integration with Excalidraw or an excellent advanced templating engine that even supports custom JavaScript execution!
Migration from Notion
After completing the first round of “lets see if this could even work” in Obsidian, it was time to tackle the burden that led me down this rabbit hole … getting my personal notes out of Notion and into a format that Obsidian could reason with. It turns out there’s an official guide to do just that, and it uses Notion’s HTML export format to extract data. An additional Importer plugin then handles the transformation of this data blob into the classic file-based structure that Obsidian can parse.
Done?
… Well, sort of?
If you only ever used Notion for storing text and maybe a few images here and there, you might be done already, but in my case, I also played around with the database feature, Kanban bords, and so on. As I would soon discover, these features just break when you export them. Great.
Databases
A database in Notion is a special kind of note that’s connected to a database, and the note itself provides a view to query the database. This does not transform well into the format Obsidian expects notes to be in. Database content in Notion can be quite arbitrary, whilst it would be best for Obsidian’s tools and features if everything was just a new note (at least that’s my current understanding). To solve this issue and transform my existing array of database entries, I’ve employed the following strategy across all of them:
- Put the entire “database” content into a folder in Obsidian.
- Move all database content files into a sub-folder
db. - Create a custom index file using
DQLto query the database (by using the excellent Dataview plugin) and make it “appear” like it would in Notion.
This is what one of these very simple database index files looks like in my current setup:
TABLE tags, link from "links/db"
Additionally, to create a new note in this database, I’ve written a custom template that handles most of the “annoying” setup for me, making it as easy as possible for me to just dump content:
<%*
let qcFileName = await tp.system.prompt("Link Note Title (auto-prefixed)")
titleName = tp.date.now("YYYY-MM-DD") + "_" + qcFileName
await tp.file.rename(titleName)
await tp.file.move("/links/db/" + titleName);
-%>
---
creation date: <% tp.file.creation_date() %>
modification date: <% tp.file.last_modified_date("dddd Do MMMM YYYY HH:mm:ss") %>
tags:
link: <% await tp.system.prompt("Insert web link") %>
---
# <% qcFileName %>
## Notes
Now I can create links by opening the command palette - typing “Create note from template”, selecting my custom template, and I’m ready to go. And everything is placed where it should be, and indexed automatically.
Kanban
Fortunately, I had just started using Kanban boards in Notion, and I decided that they should really be co-located with the respective projects on a Git platform, so I scrapped all of them from my vault.
If you do need to migrate these boards to Obsidian, you might need a similar combination of different plugins to abstract some of the functionality.
Images & Media
Notion was very simple and easy … if there was an image, I could just easily embed it into my note and it would live there. Coming from Notion and knowing the limitations of Markdown files, I was curious to how Obsidian would solve this problem … and I was a little displeased to find out that there was no “real” solution.
Here are the two main possibilities to deal with images:
- A: Dump all attachments into a central folder, like
/assetsor/attachments, and link them to the desired note - B: If a note has an attachment, it should live in a folder next to that specific note.
For everything coming out of the “automatic” migration process, the only sensible way without redoing everything is using option A (all files will initially land in your vault root and you’ll have to move them into an asset folder initially). However, for future notes, I actually prefer option B, because it keeps attachment co-location intact, and doesn’t require me to use Obsidian to understand which image belongs to what note. Additionally, when I create blog posts or content out of my notes, I can immediately use the proper attachments because they are right next to the appropriate note.
To organize this mess, I came up with the following system:
- If the note is not yet a folder and needs a media file, I create a wrapping folder with the same name
- Put the attachment inside that folder
- Link the attachment to the note
- Filter out attachments through the Dataview and use the custom index pages from before to navigate efficiently
General Plugins
One thing that makes Obsidian great is an abundance of core and community plugins that either customize app behavior, or implement entirely new features for your vault. Here are the ones I found the most useful (other than the two I’ve already mentioned above, which I consider to be required for my workflow).
AI Integration
Since all notes are now local on my device, and they also use a very standardized format, it’s actually quite feasible to feed them to a local LLM for additional context-aware suggestions. In my post on [[2024-04-22_Taming Llamas - Leveraging Local LLMs]], I go into detail about setting up a local LLM and touch on the AI Integration part with Obsidian. In essence, the plugin I’m using at the moment is Obsidian Smart Connections, and it works quite well for my use-case. It adds a chat panel to the right sidebar, which allows you to directly interface with your notes through a local LLM setup. I highly recommend giving local LLMs a try first, but if you want, you can also use this setup to with OpenAI or other commercial LLMs.
Excalidraw
I’ve been using Excalidraw for lots of different little sketches, because I like the hand-drawn aesthetics for wireframes and quick flow-charts. I’ve always been slightly scared to lose drawings I’m currently working on, since they’re stored in the browsers local storage until they are explicitly saved to disk - and you can only ever work on one drawing at a time. The excellent Obsidian Excalidraw Plugin provides a very simple and easy-to-use option to integrate Excalidraw into obsidian vaults, by bringing the entire Excalidraw editor right into obsidian. With this setup, I can now easily colocate notes with schematic drawings, wireframes, etc. - and even create links to notes within my Excalidraw drawings.
VIM Keybindings
Ever since I first tried VIM a few years ago, I’ve been trying to integrate it’s keybindings into every app I use regularly. Fortunately, Obsidian has default support for VIM keybindings, and enabling them is as simple as toggling a box in the advanced settings menu.
Sync
I already needed a new self-hosted solution to sync my Git projects, so I chose to synchronize my vault using Git. I am planning to release another post on that topic eventually, but in essence, I’m running my own Gitea server on a Hetzner Cloud Instance. Whenever I’m done working in Obsidian, I hop into my terminal and run commit-notes, which is just an alias I defined in my zsh configuration:
alias commit-notes='cd ~/notes/ && git add . && git commit -am "`date +\"%Y-%m-%d %H:%M:%S\"`" && cd -'
This allows me to commit all contents of my Obsidian vault at once without having to consciously think about a commit message. I then use another script to push the notes to my repository:
alias push-notes='cd ~/notes/ && git push origin && cd -'
With that setup, I can now easily save and synchronize my notes.
Mobile
This is still a little bit of a pain-point for me. Let me just say it straight - all solutions I found that allowed easy cross-device synchronization for Obsidian either required paying for Obsidian Sync, the proprietary subscription service, or were a little awkward to set up. On iOS, the Obsidian app allows syncing, but it’s restricted to the proprietary subscription or iCloud, both of which I do not want to use. I do use iCloud for some things, and I even pay monthly to get extra storage, but I need my notes accessible on Windows and Android as well.
Here’s the current solution I’m using (which works surprisingly well for me, at least so far):
- Mainly use a computer to edit and organize notes, with all of the plugins and tools I’ve outlined above
- Use mobile devices (phones, tablets) mainly as devices that can consume notes, but not create them
- On iOS, I use an awesome fully-featured Git client called Working Copy to access my notes repository
- Whenever I need to create a note on the go, I dump it into Apple Notes as unstructured content
- When I’m at home and unwind from the day, I transfer these notes to the vault
Verdict after 6 Weeks
I’ve actually written the first part of this article 6 weeks ago, but only now got to finishing it. Over this period, I’ve grown accustomed to the note-taking system within Obsidian and am quite content with leaving Notion behind. If I ever find a hassle-free solution for integrating this setup with mobile devices, I’ll write a new post or update this one. So far, that’s the only remaining pain point of my solution, everything else works as I would expect it to. The thing I like about my setup the most is the simplicity of just taking a markdown file from my Obsidian vault, and putting it on this blog with little to no necessary modifications. The only things I have to modify are frontmatter and meta tags at the top of the file, and I’m good to publish. This makes the whole process very straightforward and frictionless.
In the upcoming weeks, I’ll need to create more notes about scientific literature, so I’ll explore options to integrate my existing solution with Zotero, and I will probably post about my solution when I’ve found something that works well for my use-case.