---
title: "Importing from Logseq"
description: "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.**

> Read https://docs.justmimir.com/resources/llm-skills/importing-from-logseq.md and
> follow it to import my Logseq graph into Mimir. My Logseq folder is:
> (the path to your graph folder, or to the Markdown export). Before the
> full import, show me how to back up my Mimir notes and test the import on
> five pages.

## 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/` and `pages/` 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:

1. Back up your Mimir notes. See
   [Backing up and restoring](/backing-up-and-restoring).
2. Import five pages, including one journal day.
3. Check how those pages look in Mimir.
4. 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 page `YYYY-MM-DD`. The
  default file name is `2026_10_11.md`, which becomes `2026-10-11`. Mimir
  treats any page titled like that as that day's journal entry, so
  `append` with 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: `%2F` and `___` are
  `/`, and other `%XX` codes decode as usual. Namespaced titles such as
  `Projects/Mimir` stay as they are, slash included.
- **Formats in `logseq/config.edn`.** `:journal/file-name-format` sets how
  journal files are named, and `:journal/page-title-format` sets how links to
  journal days are written inside bullets. Read both before you convert, and
  fall back to the defaults (`yyyy_MM_dd` and `MMM 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: value` bullets, 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. |
| `![name](../assets/…)` | 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.
