Rsync for Notion - Sync Notion pages to local markdown files
npm install notion-rsync


One-way sync from Notion to local Markdown files. Fast, idempotent, and designed for docs-as-code workflows.
``bash`Sync your Notion workspace to markdown
notion-rsync sync --output ./docs
- Docs-as-code - Keep your documentation in git, use your favorite editor, run CI/CD on it
- LLM-friendly - Export Notion content for RAG pipelines and AI context
- Backup - Simple, readable backups of your Notion workspace
- Fast - Parallel fetching with concurrency control
- Idempotent - Safe to run repeatedly, only overwrites what changed
- Sync pages and databases (including nested databases)
- Preserves hierarchy as folder structure
- Rich frontmatter with all database properties
- Handles 20+ block types (text, lists, tables, code, callouts, toggles, equations, embeds...)
- Gracefully renders unsupported blocks (AI blocks, etc.) as HTML
- Dry-run mode for previewing changes
- Cleans up deleted pages automatically
`bashWith npm
npm install -g notion-rsync
Or run directly without installing:
`bash
npx notion-rsync sync --output ./docs
bunx notion-rsync sync --output ./docs
`Quick Start
$3
1. Go to notion.so/my-integrations
2. Click "New integration"
3. Give it a name and select your workspace
4. Copy the "Internal Integration Secret"
$3
1. Open the Notion page or database you want to sync
2. Click "..." → "Add connections"
3. Select your integration
$3
`bash
Set your token
export NOTION_TOKEN="secret_abc123..."Get your page/database ID from the URL:
https://notion.so/My-Page-abc123def456
^^^^^^^^^^^^^^^ this part
Initialize (creates .notion-rsync config)
notion-rsync init abc123def456 --output ./docsRun sync
notion-rsync sync --output ./docsOr preview first
notion-rsync sync --output ./docs --dry-run
`Output Structure
`
docs/
├── .notion-rsync/
│ └── index.json # Sync state (tracks pages for cleanup)
├── my-database/
│ ├── index.md # Database root (if it has content)
│ ├── page-one.md
│ ├── page-two/
│ │ ├── index.md # Pages with children become folders
│ │ └── nested-page.md
│ └── child-database/
│ ├── index.md
│ └── entry.md
└── standalone-page.md
`Generated Markdown
Each file includes:
`markdown
---
notion_id: abc123-def456
title: "My Page Title"
last_edited: 2024-01-15T10:30:00.000Z
status: "In Progress" # Database properties
priority: "P1" # are included in
assignee: "John Doe" # frontmatter
tags: ["feature", "urgent"]
---My Page Title
Your content here...
`Commands
$3
Initialize sync configuration for a Notion page or database.
`bash
notion-rsync init abc123def456 --output ./docs
`$3
Sync content from Notion to local markdown files.
`bash
notion-rsync sync --output ./docs [--dry-run]
`Options:
-
--output, -o - Output directory (default: ./docs)
- --dry-run, -n - Preview changes without writing files
- --verbose, -v - Enable verbose logging$3
Show sync status and configuration.
`bash
notion-rsync status --output ./docs
`Environment Variables
| Variable | Description |
|----------|-------------|
|
NOTION_TOKEN | Notion API integration token (required) |Supported Block Types
| Block Type | Markdown Output |
|------------|-----------------|
| Paragraph | Plain text |
| Headings (1-3) |
#, ##, ### |
| Bulleted list | - item |
| Numbered list | 1. item |
| To-do | - [ ] / - [x] |
| Toggle | |
| Code | Fenced code blocks |
| Quote | > blockquote |
| Callout | > emoji text |
| Divider | --- |
| Table | Markdown tables |
| Image | !alt |
| Video/File/PDF | name |
| Bookmark | title |
| Embed | title |
| Equation | $$latex$$ |
| Columns | Sequential blocks |
| Synced block | Resolved content |
| Child page | Link |
| Child database | Recursed |Supported Property Types
All Notion database property types are extracted to frontmatter:
- Text, Number, Checkbox, URL, Email, Phone
- Select, Multi-select, Status
- Date (with ranges)
- People, Files
- Formula, Relation, Rollup
- Created/Last edited time and by
- Unique ID
Development
`bash
Clone
git clone https://github.com/nonfx/notion-rsync.git
cd notion-rsyncInstall dependencies
bun installRun locally
bun run dev sync --output ./test-outputBuild
bun run buildLint & format
bun run lint
bun run format
`Roadmap
- [x] Retry logic for rate limits
- [ ] Progress indicators
- [ ] Configuration file support
- [ ] Image downloading (optional)
- [ ] Two-way sync (future)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (
git checkout -b feature/amazing-feature)
3. Commit your changes (git commit -m 'Add amazing feature')
4. Push to the branch (git push origin feature/amazing-feature`)MIT - see LICENSE for details.