Skip to main content

Logseq → Obsidian Converter

tests lint codecov

Overview

  • Converts a Logseq vault (Markdown flavor) to Obsidian-friendly Markdown.
  • Handles page properties → YAML front matter, task statuses, block IDs, block references, org-mode blocks → callouts, highlights, numbered lists, and more.
  • Preserves non-page folders; moves pages/ content to the vault root.

Features

  • Page properties (key:: value) at top → YAML front matter.
    • Values are quoted when plain YAML would break or silently change them (e.g. Note: important, #book); numbers, booleans and dates stay unquoted so Obsidian keeps their property type.
  • Special mappings:
    • alias:: or aliases:: → aliases: [] (array)
    • tags:: → tags: [] (array, without #)
    • title:: → omitted (Obsidian only uses the filename as the note name). If the Logseq title mismatches the vault-relative output path, a warning is emitted so you can tidy it up.
  • Task markers:
    • Recognized at the start of a list item (- STATE ..., uppercase only):
      • TODO, DOING, LATER, NOW, WAIT, WAITING, IN-PROGRESS → - [ ] ...
      • DONE, CANCELED, CANCELLED → - [x] ...
    • Priorities right after state ([#A|#B|#C]):
      • Emoji: A→⏫, B→🔼, C→🔽 (appended at end)
      • Dataview: [priority::high|medium|low] (appended at end; omitted if none)
    • Dates anywhere after the state:
      • SCHEDULED: <YYYY-MM-DD [Dow] [HH:MM] [repeater]> → Emoji: ⏳ YYYY-MM-DD[ HH:MM]; Dataview: [scheduled::YYYY-MM-DD[ HH:MM]]
      • DEADLINE: <YYYY-MM-DD [Dow] [HH:MM] [repeater]> → Emoji: 📅 YYYY-MM-DD[ HH:MM]; Dataview: [due::YYYY-MM-DD[ HH:MM]]
      • Repeaters: . +N<u> or ++N<u> → “every N when done”; +N<u> → “every N ”
      • Units: y=year(s), m=month(s), w=week(s), d=day(s), h=hour(s); pluralized when N ≠ 1
      • Ordering: append priority, then scheduled, then due, then repeat; block anchors (e.g., ^id) remain last
  • Block IDs:
    • id:: <uuid> lines are converted to Obsidian block anchors by appending ^<uuid> to the owning block line.
  • Block references:
    • ((<uuid>)) → [[<FileName>#^<uuid>]] (resolved by scanning all files first).
    • Optional: convert configured wikilinks [[key/value]] to Dataview inline fields [key::value] (non-embed, no alias, not inside code blocks).
  • Alias links:
    • [Display Name]([[Page Name]]) → [[Page Name|Display Name]] (outside fenced code blocks).
  • Embeds:
    • {{embed ((<uuid>))}} → ![[<FileName>#^<uuid>]] (left unchanged if the block id cannot be resolved)
    • {{embed [[Some Page]]}} → ![[Some Page]]
    • {{video https://...}} → ![](https://...)
    • {{youtube https://...}} → ![](https://...)
    • {{tweet https://...}} → ![](https://...)
  • Images in assets:
    • ![alt](../assets/image.png) or ![alt](assets/image.png) → ![[image.png]] (alt text is not preserved)
    • With size attributes: ![alt](../assets/image.png){:height H, :width W} → ![[image.png|WxH]] (width × height)
    • Remote images (https://..., data:..., //...) are left unchanged.
  • Org-mode blocks:
    • #+BEGIN_QUOTE ... #+END_QUOTE → > blockquote lines.
    • #+BEGIN_NOTE, #+BEGIN_TIP, #+BEGIN_WARNING, #+BEGIN_IMPORTANT, #+BEGIN_CAUTION, #+BEGIN_EXAMPLE → Obsidian > [!type] callouts. The first bold line inside the block becomes the callout title.
    • #+BEGIN_COMMENT ... #+END_COMMENT → %% ... %% (Obsidian hidden comments).
    • Other admonition-like block types (CENTER, VERSE, PINNED) fall back to > [!note].
    • Unknown block types (e.g. #+BEGIN_SRC, #+BEGIN_QUERY) are left unchanged, so code and query content is preserved verbatim.
    • Nested blocks are supported (e.g., a quote inside a callout produces nested > > ...).
    • Blocks inside indented list items preserve their indentation in output.
    • This handles org-style block syntax embedded in Logseq's Markdown files; it does not add support for Logseq vaults stored in Org format (.org files).
  • Highlights:
    • ^^text^^ → ==text== (Obsidian highlight syntax). Skipped inside code.
  • Numbered lists:
    • Logseq stores numbered lists as regular bullets with a hidden logseq.order-list-type:: number property. These are converted to standard Markdown numbered lists (1., 2., 3....) with correct sequential numbering that resets across indent levels and non-numbered items.
  • Task date properties:
    • created:: [[YYYY-MM-DD]] or created:: YYYY-MM-DD → Emoji: appends ➕ YYYY-MM-DD; Dataview: [created::YYYY-MM-DD]
    • completed:: ... or done:: ... → Emoji: appends ✅ YYYY-MM-DD; Dataview: [completion::YYYY-MM-DD]
    • cancelled:: ... or canceled:: ... → Emoji: appends ❌ YYYY-MM-DD; Dataview: [cancelled::YYYY-MM-DD]
    • Works with or without a leading dot (e.g., .created::) and with or without [[]] around the date.
    • The date is appended to the task the property belongs to; on blocks that are not tasks the property is kept unchanged.
  • Logseq metadata cleanup:
    • :LOGBOOK: ... :END: time-tracker blocks are removed.
    • Remaining logseq.* namespaced block properties (e.g., logseq.toc::) are removed.
  • Code:
    • Content inside fenced code blocks and inline code spans is never transformed; Logseq syntax there (tasks, properties, block refs, embeds, images, highlights, links) is kept verbatim.
  • Headings followed by indented lists:
    • If a heading line is immediately followed by an indented list (≥4 spaces or tabs), prefix the heading with - (i.e., - # Heading).
    • Rationale: Logseq treats such lists as children of the heading; Obsidian otherwise renders them as quoted/code blocks. This keeps folding behavior aligned.
  • Journals:
    • Renames YYYY_MM_DD.md → YYYY-MM-DD.md and can move journals to a specific folder.
  • Assets and other files are copied as-is.

Installation

  • pipx (recommended): pipx install logseq-to-obsidian
  • pip: pip install logseq-to-obsidian
  • From Git (development version): pipx install "git+https://github.com/sercxanto/logseq_to_obsidian.git@main"

Usage

logseq-to-obsidian \
  --input /path/to/logseq-vault \
  --output /path/to/obsidian-vault \
  --daily-folder "Daily Notes" \
  --tasks-format emoji \
  --field-key project \
  --field-key topic \
  --dry-run

Alternatively (no console script), you can run:

python -m logseq_to_obsidian \
  --input /path/to/logseq-vault \
  --output /path/to/obsidian-vault \
  --dry-run

Options

  • --input: Path to the Logseq vault root (folder containing pages/, journals/, etc.).
  • --output: Destination Obsidian vault directory (created if not exists).
  • --daily-folder <name>: Move journals/ into this folder in the output. If omitted, keeps journals/.
  • --tasks-format {emoji|dataview}: Choose output format for Tasks metadata (priorities now; dates later). Default: emoji.
  • --field-key <key>: Convert wikilinks of the form [[key/value]] to Dataview inline fields [key::value]. Repeatable for multiple keys.
  • Pages are always flattened to the vault root; see "File placement rules" below.
  • --dry-run: Print planned changes without writing files.

Notes and assumptions

  • Only Markdown (.md) files are transformed; other files are copied.
  • Block reference resolution requires that id:: appears for referenced blocks in the source files. Unresolved block references and embeds are left unchanged and reported with one warning per file.
  • This tool is conservative: it preserves unknown page properties in YAML.
  • Block-level collapsed:: properties are ignored; Obsidian stores list collapse state outside Markdown.

Limitations

  • Does not parse or migrate the Logseq database; operates purely on Markdown files.
  • Skips Logseq's internal logseq/ metadata folder.
  • Skips a top-level .git/ directory if present.
  • Skips Logseq whiteboards (whiteboards/); a warning is emitted since Obsidian cannot read Logseq's whiteboard format.
    • Only normalizes heading + indented list patterns outside fenced code blocks; headings already inside list items are left unchanged.
  • Logseq percent-encodes invalid characters in filenames; this tool preserves those filenames and emits a warning when detected. It does not attempt to decode them to avoid invalid output names or collisions, so you may need to rename notes in Logseq first if Obsidian links are broken.
  • Please make sure that the Logdeq's file name format is triple-lowbar, see the documentation
  • File times are preserved: output files keep the original source modification time (mtime) for both transformed Markdown and copied assets.

File placement rules

  • Pages: All files from Logseq's pages/ are placed at the root of the Obsidian vault.
  • Nested paths: Logseq encodes subfolders in page filenames using three underscores ___.
    • Example: pages/a___b.md becomes a/b.md.
  • Collisions: if several source files map to the same output path (e.g. pages/a___b.md and pages/a/b.md, or pages/Foo.md and pages/foo.md, compared case-insensitively), only the first one in sorted path order is converted. The others are skipped with a warning so nothing is overwritten silently.

Journals

  • Journal filenames are always renamed from YYYY_MM_DD.md to YYYY-MM-DD.md.
  • Logseq already displays journal page links using dashes (e.g., [[2024-08-30]]), so link text does not need conversion.

Development / Contributing

See CONTRIBUTING.md

Metadata

Release files for logseq-to-obsidian 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for logseq-to-obsidian 0.2.1
File Size Uploaded Provenance Actions
logseq_to_obsidian-0.2.1.tar.gz 27.3 kB With provenance Details for logseq_to_obsidian-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for logseq-to-obsidian 0.2.1
File Interpreter ABI Platform Actions
logseq_to_obsidian-0.2.1-py3-none-any.whl Python 3 none any Details for logseq_to_obsidian-0.2.1-py3-none-any.whl

Total release size: 53.4 kB

Release files / logseq_to_obsidian-0.2.1.tar.gz

Download URL logseq_to_obsidian-0.2.1.tar.gz
Size 27.3 kB
Tags Source
SHA-256 checksum
How to use checksums
71ab6801d5a8b2cc07563085436b020a7705962e261acde6b0c7595ac11b918f
BLAKE2b-256 checksum
How to use checksums
6f3395c3c089181c835164dbc72ed0b112a49d756a00c6972d7f476cd3604199
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Release files / logseq_to_obsidian-0.2.1-py3-none-any.whl

Download URL logseq_to_obsidian-0.2.1-py3-none-any.whl
Size 26.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ee8b92f0b0e7f235a2c59003c62572ad713a6921611ca98e5a172c17b6b7bc47
BLAKE2b-256 checksum
How to use checksums
aab549795bd5a8edd1fb136ed8e8583d94c2a9f6eb28459adb52dc688abb0ead
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Security for logseq-to-obsidian 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for logseq_to_obsidian-0.2.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page