Obsidian2notion
Sync entire obsidian library to notion database with images included. Minimal user intervention after initial setup, can be run multiple times without duplicating values to provide a backup like experience. Spent about 4 hours vibe coding and troubleshooting this with Gemini. Works on my computer right now with images uploading correctly.
Install / Use
/learn @DrSchnitzel57/Obsidian2notionREADME
Notion Sync & Backup Toolkit
A comprehensive collection of Node.js scripts for syncing between Notion, markdown files, and managing your Notion workspace. Perfect for backing up Notion to Obsidian, syncing markdown files to Notion, and maintaining your knowledge base.
🌟 Features
- 📤 Markdown to Notion Sync: Upload markdown files and images to Notion databases
- 📥 Notion to Markdown Backup: Complete workspace backup in Obsidian-compatible format
- 🧹 Database Cleanup: Remove duplicate and unwanted pages
- 📁 Centralized Attachments: Organize images in a single attachments folder
- ⚡ Incremental Sync: Only process changed files for faster operations
- 🔄 Batch Processing: Handle large workspaces efficiently
- 🖼️ Image Management: Download, upload, and organize images automatically
📋 Table of Contents
- Quick Start
- Scripts Overview
- Installation
- Configuration
- Usage Examples
- File Structure
- Troubleshooting
- Contributing
🚀 Quick Start
-
Clone the repository
git clone <your-repo-url> cd notion-importer -
Install dependencies
npm install -
Set up environment
cp .env.example .env # Edit .env with your Notion integration token -
Configure your setup
# Edit config.js to match your folder structure -
Run your first backup
npm run backup
📜 Scripts Overview
🔄 sync-to-notion.js
Purpose: Upload markdown files and images to Notion databases
Features:
- Converts markdown to Notion blocks
- Uploads images to S3 and links them in Notion
- Creates databases based on folder structure
- Handles nested directories
- Supports frontmatter metadata
Usage:
node sync-to-notion.js
# or
npm start
Best For:
- Moving your Obsidian vault to Notion
- Regular sync from markdown files to Notion
- Bulk import of documentation
📥 notion-backup.js
Purpose: Complete backup of Notion workspace to markdown format
Features:
- Exports all databases and pages
- Downloads all images locally
- Creates Obsidian-compatible markdown
- Incremental backup support (only changed files)
- Preserves metadata and creation dates
- Centralized attachments folder
Usage:
node notion-backup.js
# or
npm run backup
Output Structure:
notion-backup/
├── README.md
├── Attachments/ # All images in one place
├── Database Name 1/
│ ├── Page 1.md
│ ├── Page 2.md
│ └── ...
├── Database Name 2/
└── .backup-state.json # Tracks changes for incremental sync
Best For:
- Creating backups of your Notion workspace
- Migrating from Notion to Obsidian
- Archiving important content
🧹 notion-page-cleanup.js
Purpose: Clean up and organize Notion databases
Features:
- Remove duplicate pages
- Delete empty or unwanted content
- Batch operations for efficiency
- Safe dry-run mode
- Detailed logging of actions
Usage:
node notion-page-cleanup.js
# or
npm run cleanup
Best For:
- Cleaning up after bulk imports
- Removing test pages
- Database maintenance
🛠️ Installation
Prerequisites
- Node.js 14+
- npm or yarn
- Notion account with integration access
- (Optional) AWS account for S3 image hosting
Step-by-Step Setup
1. Clone and Install
git clone https://github.com/your-username/notion-importer.git
cd notion-importer
npm install
2. Notion Setup
Create a Notion Integration:
- Go to www.notion.so/my-integrations
- Click New integration
- Name it (e.g., "Markdown Sync")
- Copy the Internal Integration Secret (this is your
NOTION_TOKEN)
Set Up Your Database:
- Create a new database in Notion
- Copy the Database ID from the URL:
https://www.notion.so/your-workspace/DATABASE_ID?v=... - Add these exact property names to your database:
- Name (Title) - automatically exists
- Path (Text) - for file paths
- Has Images (Checkbox) - tracks image content
- Created Date (Date) - file creation date
Share Database with Integration:
- On your database page, click Share
- Click Invite and select your integration
- Grant access to the integration
3. AWS S3 Setup (Optional - for Image Hosting)
⚠️ Privacy Note: This method makes your images publicly accessible on the internet to anyone with the direct link. While links are long and unguessable, they are not private. This is the trade-off for automated, permanent image hosting in Notion.
Create S3 Bucket:
- Go to AWS S3 Console
- Click Create bucket
- Choose a globally unique name (e.g.,
yourname-notion-assets) - Select a region near you (e.g.,
us-west-2)
Make Bucket Public:
- Click on your bucket → Permissions tab
- Under Block public access, click Edit
- Uncheck "Block all public access" → Save changes → type
confirm - Under Bucket policy, click Edit and paste:
Replace{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*" } ] }YOUR_BUCKET_NAMEwith your actual bucket name.
Create IAM User:
- Go to AWS IAM Console
- Users → Create user → name it
notion-s3-uploader - Attach policies directly → Create policy
- Use JSON editor and paste:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*" } ] } - Name the policy
NotionS3UploadAccessand attach to user - Go to user → Security credentials → Create access key (CLI option)
- Copy both Access key ID and Secret access key
4. Environment Configuration
# Copy the example environment file
cp .env.example .env
Edit .env with your values:
# Required: Notion Integration Token
NOTION_TOKEN=secret_1234567890abcdef...
# Optional: S3 Configuration (for permanent image hosting)
AWS_ACCESS_KEY_ID=your_access_key_here
AWS_SECRET_ACCESS_KEY=your_secret_access_key_here
S3_BUCKET_NAME=your-notion-images-bucket
S3_REGION=us-east-1
S3_DOMAIN=your-bucket.s3.amazonaws.com
# Optional: Testing and debugging
DRY_RUN=false
DEBUG=false
⚙️ Configuration
Environment Variables (.env)
# Required: Notion Integration Token
NOTION_TOKEN=secret_1234567890abcdef...
# Optional: S3 Configuration (for image uploads)
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
S3_BUCKET_NAME=your-bucket-name
S3_REGION=us-east-1
# Optional: S3 Domain (for migration scripts)
S3_DOMAIN=your-bucket.s3.amazonaws.com
# Optional: Dry run mode (for testing)
DRY_RUN=false
Configuration File (config.js)
module.exports = {
// Base directory for markdown files
markdownBaseDir: path.join(__dirname, 'my-markdown-files'),
// Attachments folder name
attachmentsDir: 'Attachments',
// Processing limits
concurrencyLimit: 5,
// Root database name
rootDatabaseName: 'Root',
};
Project Folder Structure
Create your markdown files in the recommended structure:
notion-importer/
├── my-markdown-files/ # Your markdown content
│ ├── Projects/
│ │ ├── Project A.md
│ │ └── Project B.md
│ ├── Notes/
│ │ ├── Meeting Notes.md
│ │ └── Research.md
│ └── Attachments/ # Centralized images folder
│ ├── screenshot1.png
│ ├── diagram.jpg
│ └── document.pdf
├── notion-backup/ # Generated backups
├── src/ # Script utilities
├── .env # Your configuration
└── config.js # Folder settings
Important Notes:
- Create a
my-markdown-filesfolder for your content - Use an
Attachmentssubfolder for all images - Folder names become Notion database names
- File names become Notion page titles
📖 Usage Examples
Example 1: Backup Your Notion Workspace
# Full backup
npm run backup
# The script will:
# 1. Find all databases in your workspace
# 2. Export each page as markdown
# 3. Download all images to Attachments/
# 4. Create an index file
# 5. Save state for incremental backups
Example 2: Sync Markdown Files to Notion
# Sync your markdown folder to Notion
npm start
# The script will:
# 1. Scan your markdown files directory
# 2. Create databases for each folder
# 3. Upload markdown content as Notion pages
# 4. Upload images to S3 and link them
Example 3: Clean Up Notion Database
# Review and clean databases
npm run cleanup
# The script will:
# 1. Show you duplicate or empty pages
# 2. Ask for confirmation before deletion
# 3. Clean up the database structure
📁 File Structure
notion-importer/
├── README.md # This file
├── BACKUP_README.md # Detailed backup documentation
├── package.json # Node.js dependencies and scripts
├── config.js # Main configuration file
├── .env # Environment variables (create this)
├── .gitignore # Git ignore patterns
│
├── src/ # Core utilities
│ ├── notion.js # Notion API wrapper
│ ├── utils.js # Helper functions
│ └── s3.js # S3 upload utilities
│
├── sync-to-notion.js # 📤 Main sync script
├── notion-backup
