Importing from Logseq
Bring a Logseq graph into Mimir: hand this page to an AI assistant and it writes and runs the import, journal days and links included.
This page is written for you and for an AI assistant at the same time. You give it to your assistant, and the assistant writes a script that sends your Logseq pages into Mimir, one page at a time. Your journal days land on the same days in Mimir’s journal, and your links keep working.
Ask an AI assistant to import your Logseq graph.
Before you start
The import reads a folder of Markdown files:
- Logseq OG keeps your graph as Markdown already. Use the graph folder,
the one with
journals/andpages/in it. Org-mode (.org) pages aren’t covered. - Logseq 2.0 keeps your graph in a database. Export it first: open the menu with three dots, choose Export graph, then Export as standard Markdown (no block properties). Use the folder it produces.
Images and other files in assets/ stay behind. A bullet that showed an
image keeps the image’s name as text.
Then work through it in this order:
- Back up your Mimir notes. See Backing up and restoring.
- Import five pages, including one journal day.
- Check how those pages look in Mimir.
- Import the rest.
Running the import twice adds every page a second time. If the test pages look wrong, restore your backup before you try again.
For the assistant: the route
Mimir has no import command and no file format to write. Don’t write into Mimir’s database file. It holds a history of changes, not a table of bullets. Send each Logseq page through one link:
mimir://append?page=<title>&text=<text>
<title> and <text> are URL-encoded, with spaces as %20, not +. Mimir
creates the page if it doesn’t exist and adds the text to the end of it. Page
titles match without regard to case or repeated spaces, so Book Notes and
book notes are the same page. On macOS, open each link with open:
open "mimir://append?page=Groceries&text=..."
Send one link at a time, with a pause of a second or two between them. Mimir opens each page as its text arrives.
A long page may not fit in a URL. For those, put the page’s text on the
clipboard (pbcopy on macOS) and open the link without text:
mimir://append?page=<title>. Mimir pastes the clipboard instead. Send each
page whole, in one link. Each link adds to the end of the page, so a page
split across links has to go in order.
For the assistant: page titles
- Journal days. A file in
journals/becomes the pageYYYY-MM-DD. The default file name is2026_10_11.md, which becomes2026-10-11. Mimir treats any page titled like that as that day’s journal entry, soappendwith that title lands on the right day. If a day already has bullets in Mimir, the imported bullets go below them. - Other pages. Use the page’s
title::property when the file has one. Otherwise use the file name without.md, decoded:%2Fand___are/, and other%XXcodes decode as usual. Namespaced titles such asProjects/Mimirstay as they are, slash included. - Formats in
logseq/config.edn.:journal/file-name-formatsets how journal files are named, and:journal/page-title-formatsets how links to journal days are written inside bullets. Read both before you convert, and fall back to the defaults (yyyy_MM_ddandMMM do, yyyy) only when they’re missing.
For the assistant: how the text becomes bullets
Mimir splits the text you send into bullets, one per list item. Logseq’s own
file shape already fits: each - line becomes a bullet, tabs or spaces in
front of it become nesting, and an indented line without a dash joins the
bullet above it as a second line. Send the page body as Logseq wrote it, after
the conversions below.
Look at a few files before you write the script. If the bullets in them aren’t
- lists, which can happen with a Logseq 2.0 export, put - in front of
each paragraph, and check whether logseq/config.edn exists before relying
on it.
Watch for these:
- A page with one bullet arrives as a single bullet with the text exactly as
sent, so strip its leading
-first. - Lines before the first
-(page properties, usually) make Mimir nest the whole page under them. Turn each such line into its own-bullet at the top of the page. - Code blocks inside a bullet. Lines in a fenced block that start with
-or*split off as separate bullets, and indentation inside the block flattens. Check pages with code by hand after the import. - Front matter, the block between
---lines at the top of a file, becomes plain text. Turn its lines into- key: valuebullets, the same as page properties.
For the assistant: converting Logseq syntax
Convert each bullet’s text before sending it. Leave anything inside
`code` or a code fence exactly as written. When this table says to keep
something as text, keep the words and drop only what the table names.
| Logseq | In Mimir |
|---|---|
[[Page]] |
Keep. Same syntax, a link to the page. |
#tag, #[[two words]] |
[[tag]], [[two words]]. Mimir has no tags. Only a # at the start of a word counts, so leave the # in a URL alone. |
[[Oct 11th, 2026]] (a link to a journal day) |
[[2026-10-11]]. Use the title format from config.edn. |
[label]([[Page]]) |
[[Page]] |
[label](https://…) |
label https://…. Mimir has no Markdown links and shows bare URLs as links. |
 |
The file name as text, for example photo.png. |
TODO, DONE at the start of a bullet |
Keep. Mimir reads todo and done there as its to-do marker, in any capitalization. |
LATER, NOW, DOING, WAITING, IN-PROGRESS |
TODO |
CANCELED, CANCELLED |
DONE |
[#A], [#B], [#C] |
Keep as text. |
SCHEDULED: <…>, DEADLINE: <…> |
Keep as text, on the bullet’s second line. |
:LOGBOOK: … :END: |
Remove, lines and all. |
key:: value |
key: value, as text on the bullet’s own lines. |
id::, collapsed::, heading:: |
Remove. |
((uuid)) |
The text of the bullet with that id::, then a link to its page: the bullet's text ([[Source page]]). |
{{embed ((uuid))}} |
Same as ((uuid)). Its child bullets don’t come along. |
{{embed [[Page]]}} |
[[Page]] |
{{query …}} |
Keep as code: `{{query …}}`. Mimir has no queries. |
{{youtube https://…}}, {{video https://…}} |
The bare URL, alone in its bullet. Mimir offers to embed a video link on its own line. |
==highlight==, ^^highlight^^ |
Remove the markers, keep the words. |
~~strikethrough~~ |
Remove the markers, keep the words. Mimir hides text between single tildes, so ~~ would hide it. |
**bold**, *italic*, `code`, code fences |
Keep. Same syntax. |
# Heading at the start of a bullet |
Keep. Same syntax. |
> quote |
Keep. Mimir shows it as a guest block, someone else’s words. |
#+BEGIN_QUOTE … #+END_QUOTE |
> in front of each line inside. Drop the two marker lines. |
To resolve ((uuid)), first read every file and collect each id:: with
its bullet’s first line and page title. Use that first line only, converted,
with any TODO-style marker removed. Its other lines and child bullets stay
behind. A reference whose id:: isn’t found stays as ((uuid)) text.
For the assistant: checking the test pages
After the five test pages, ask the person to open them in Mimir and check:
- The journal day shows up on the right date in the journal.
- Nesting matches Logseq.
- Links go to the right pages, and no page has a title like
Oct 11th, 2026. - No text is masked. Masked text points to tildes left in the text.
Only then import the rest.
