Skip to content

Importing from other tools

Subspace imports from the three tools people most often arrive from. Go to settings, then import (/settings/import), pick a format, choose your export file, and run a dry run before you commit to anything.

Format What to upload
Obsidian Markdown A zipped vault, or a single .md file
Notion export A zipped export, or a single .md file
Roam JSON A zip containing the .json, or a bare .json
  1. Dry run

    Press dry run. Your file is parsed in full but nothing is written. You get a summary of what would land, counted as pages, nodes, links, and assets, plus a collapsible list of upgrade notes for anything the importer recognized but could not map cleanly (see below).

  2. Import

    Press import. Landing happens in the background and the page tells you so; progress appears in the task queue as a card titled Import <filename> showing how many pages have been written so far.

A dry run parses the same way the real import does, so a malformed or unsupported archive fails at the dry run rather than halfway through writing pages.

Every note becomes an ordinary page, built through the same command pipeline as any edit you make by hand. That means links, search indexing, permissions, the filesystem bridge, and undo all work on imported content immediately.

  • Structure. Markdown bullets nest by indentation. Non-bullet lines become top-level bullets. Headings keep their text and lose their # markers.
  • Titles. The first # heading becomes the page title, falling back to the filename. Notion’s trailing page ids are stripped, so Project Plan a1b2c3... imports as Project Plan.
  • Links and tags. [[wiki links]] and #tags are carried through as text and resolved by the ordinary link resolver, so a reference to a note that imports later still connects.
  • Attachments. Images and files referenced by a note are imported as blobs and attached to the page that referenced them.
  • Frontmatter. YAML frontmatter is preserved on the page’s metadata under metadata.import.frontmatter.

Imported pages land at the top level of your workspace. Slugs come from titles, and a title that collides with an existing page gets a numeric suffix rather than merging into it.

The importer never silently drops something it recognized. Anything it cannot map yet is counted and listed under upgrade notes in the report, so you can decide whether to proceed. Today those are:

  • Frontmatter and Notion database properties are kept as raw metadata rather than converted into typed properties.
  • Notion database CSVs are retained as an upgrade path rather than becoming pages or a view.
  • Roam block references (((...))) are counted but not yet rewired to the blocks they point at.
  • Unreferenced assets in a vault are reported rather than imported.

Uploads are capped at 64 MB by default. The cap is configurable with SUBSPACE_IMPORT_MAX_BYTES, though the archive reader enforces its own 64 MB ceiling, so raising it above that does not admit larger archives. An archive may contain up to 10,000 entries.

For safety the archive reader rejects encrypted entries, symlinks, absolute paths, and paths that escape the archive.