Skip to content

Commands

Brandon Young edited this page Nov 5, 2026 · 1 revision

Commands

Every command accepts the global flags -c/--config, -v/--verbose and --timeout (default 30m); see Configuration. notion-md-sync <command> --help prints the same information as this page.

Command Does
init Interactive project setup
verify Checks the configuration
pull Notion → Markdown
push Markdown → Notion (staged files, or one file)
sync Push, pull or both, in one command
status / add / reset Git-like staging
watch Pushes files as you save them
tui Terminal user interface
completion Shell completion script (see Installation)

init

notion-md-sync init

Asks for your token, parent page ID and Markdown folder, then writes config.yaml, .env, .env.example and a sample welcome.md. It needs an interactive terminal. Details are in Configuration.

verify

notion-md-sync verify

Loads the configuration and prints the parent page, the Markdown root, the sync direction and the conflict setting. Run it first when something doesn't work.

pull

Pulls the parent page and everything under it into the Markdown root. Each page lands in Page/Page.md, and databases are exported as CSV files next to the page that holds them. See Directory Layout and Kept Blocks and Databases.

notion-md-sync pull                         # everything under the parent page
notion-md-sync pull --verbose               # with per-page progress
notion-md-sync pull --dry-run               # say what would happen, change nothing
notion-md-sync pull --directory ./notes     # into another folder (created if missing)
notion-md-sync pull --page "Meeting Notes.md"
notion-md-sync pull --page-id <PAGE_ID> -o docs/page.md
Flag Meaning
--directory <dir> Pull into this folder instead of markdown_root
--dry-run Show what would be pulled
--page <file name> Pull one page. A local file of that name with a notion_id is refreshed from its page; otherwise the page with that title is found under the parent page.
--page-id <id> Pull one page by ID. Needs -o.
-o, --output <path> Where to write the page given with --page-id

Files you have moved stay where you put them: pull matches files to pages by notion_id, not by path. After a pull, the pulled files show as clean in status.

push

notion-md-sync push                   # push everything staged with `add`
notion-md-sync push docs/page.md      # stage and push this one file
notion-md-sync push --dry-run         # show what would be pushed

push takes at most one file. To push several, stage them with add and run push with no argument.

Flag Meaning
--directory <dir> Folder holding the Markdown files (defaults to markdown_root)
--dry-run Show what would be pushed

What a push does:

  • Existing page (file has a notion_id): the file is compared with the page's current blocks. Unchanged blocks are left alone. Edited blocks are updated in place, so their IDs, comments and links survive. Only blocks with no match are inserted or deleted. If the frontmatter title changed, the page is renamed, unless the page also changed in Notion since your last sync. In that case you get a warning and should pull first.
  • New file (no notion_id): a page is created under the page of the file's folder, and its ID is written back into the frontmatter. See Directory Layout and Kept Blocks.
  • Kept blocks are never deleted: sub-pages, databases, and blocks Markdown can't express.
  • Failure safety: new blocks are uploaded before old ones are removed. If a step fails, the inserted blocks are deleted and edited blocks are restored, so the page is left as it was.
  • Files with sync_enabled: false in their frontmatter are skipped.

sync

notion-md-sync sync push                  # same as `sync` with no argument
notion-md-sync sync pull
notion-md-sync sync bidirectional
notion-md-sync sync push -f docs/page.md  # one file
notion-md-sync sync bidirectional --dry-run
Flag Meaning
[direction] or -d, --direction push (default), pull or bidirectional
-f, --file <path> Sync one file only
--directory <dir> Folder holding the Markdown files
--dry-run Show what would be synced

sync push pushes every Markdown file under the root, staged or not. bidirectional pulls and pushes. When a file and its page both changed, it applies sync.conflict_resolution (see Configuration). The sync.direction setting in config.yaml is not read here: pass the direction explicitly.

status

notion-md-sync status

Shows the parent page's title, then files grouped like git status:

On parent page: My Project Documentation

Changes staged for sync:
  (use "notion-md-sync reset <file>..." to unstage)
        staged:   docs/overview.md

Changes not staged for sync:
  (use "notion-md-sync add <file>..." to stage changes)
        modified: docs/api-guide.md
        deleted:  docs/old-notes.md

Untracked files:
  (use "notion-md-sync add <file>..." to include in what will be synced)
        docs/new-page.md

Changes are detected by modification time and content hash. Staging state is stored in .notion-sync/ in the project folder.

add

notion-md-sync add docs/page.md docs/other.md
notion-md-sync add docs/        # everything under docs/
notion-md-sync add .            # every changed file

reset

notion-md-sync reset docs/page.md   # unstage one file
notion-md-sync reset                # unstage everything (same as `reset .` or `--all`)

The files themselves are not changed.

watch

notion-md-sync watch
notion-md-sync watch --interval 3s

Watches markdown_root and pushes each .md file shortly after it is saved. --interval sets how long to wait after the last change (default 1s). Excluded paths are ignored. Stop it with Ctrl+C.

tui

notion-md-sync tui

A split-pane terminal interface: files with their sync status on the left, operation progress on the right.

Key Action
Tab Switch between the panes
↑ ↓ Move within the pane
Space Select / deselect a file
a / n Select all / select none
s Sync the selected files
p Pull (selected files, or everything)
P Push (selected files, or everything)
i Initialise a project in the current folder
c Enter Notion credentials
u Back to the main view
q, Ctrl+C Quit

Clone this wiki locally