SkillAgentSearch skills...

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/Obsidian2notion
About this skill

Quality Score

0/100

Supported Platforms

Gemini CLI

README

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

  1. Clone the repository

    git clone <your-repo-url>
    cd notion-importer
    
  2. Install dependencies

    npm install
    
  3. Set up environment

    cp .env.example .env
    # Edit .env with your Notion integration token
    
  4. Configure your setup

    # Edit config.js to match your folder structure
    
  5. 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:

  1. Go to www.notion.so/my-integrations
  2. Click New integration
  3. Name it (e.g., "Markdown Sync")
  4. Copy the Internal Integration Secret (this is your NOTION_TOKEN)

Set Up Your Database:

  1. Create a new database in Notion
  2. Copy the Database ID from the URL: https://www.notion.so/your-workspace/DATABASE_ID?v=...
  3. 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:

  1. On your database page, click Share
  2. Click Invite and select your integration
  3. 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:

  1. Go to AWS S3 Console
  2. Click Create bucket
  3. Choose a globally unique name (e.g., yourname-notion-assets)
  4. Select a region near you (e.g., us-west-2)

Make Bucket Public:

  1. Click on your bucket → Permissions tab
  2. Under Block public access, click Edit
  3. Uncheck "Block all public access" → Save changes → type confirm
  4. Under Bucket policy, click Edit and paste:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
            }
        ]
    }
    
    Replace YOUR_BUCKET_NAME with your actual bucket name.

Create IAM User:

  1. Go to AWS IAM Console
  2. UsersCreate user → name it notion-s3-uploader
  3. Attach policies directlyCreate policy
  4. Use JSON editor and paste:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "s3:PutObject",
                "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
            }
        ]
    }
    
  5. Name the policy NotionS3UploadAccess and attach to user
  6. Go to user → Security credentialsCreate access key (CLI option)
  7. 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-files folder for your content
  • Use an Attachments subfolder 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
View on GitHub
GitHub Stars23
CategoryData
Updated16d ago
Forks5

Languages

JavaScript

Security Score

90/100

Audited on Mar 24, 2026

No findings