github-to-notion
v0.2.0
Published
Sync selected GitHub markdown documents to existing Notion pages with repo-native link resolution.
Downloads
176
Maintainers
Readme
github-to-notion
Sync GitHub repo markdown documents to Notion, with the repo serving as the source of truth for document content.
What it does
- Syncs only the markdown files you map in
notion-sync.yaml - Rewrites relative document links to GitHub blob URLs
- Rewrites relative image links to raw GitHub asset URLs
- Infers
github.repoandgithub.branchfrom git or GitHub Actions when possible - Uses Notion's markdown content API instead of block-by-block conversion
- Skips no-op updates by comparing canonical markdown, not raw file formatting
- Promotes a leading
# H1to the Notion page title by default - Works as both a CLI and a GitHub Action
Constraints
- Target pages are managed pages. Manual content edits in Notion will be overwritten on the next sync.
- Page-level discussion works well. Block-anchored comments can move or disappear when the underlying content changes.
- The target page must round-trip as markdown. If it contains unsupported blocks, child pages, or truncated content, the sync fails with a clear error instead of guessing.
Installation
npm install github-to-notionNode 20 or newer is required.
Notion setup
- Create an internal integration in Notion.
- Share each target page with that integration.
- Provide the token through
NOTION_TOKENor the action input.
If you want page titles to stay in sync, the integration also needs permission to update the target pages.
Config
Create notion-sync.yaml in your repository root:
github:
repo: your-org/your-repo
branch: main
# host: github.com
documents:
- id: readme
source: README.md
page: https://www.notion.so/Your-Page-Title-abc123def456abc123def456abc123de
- id: architecture
source: docs/architecture.md
page: abc123def456abc123def456abc123de
title: Architecture
options:
source_notice: trueNotes:
github.repois optional when the current checkout or GitHub Actions environment already exposes it.github.branchis optional when the current checkout or GitHub Actions environment already exposes it.pageaccepts a Notion URL, a dashed UUID, or a 32-character page ID.notion_pageis still accepted as a legacy alias for the prototype config.- If the document starts with a leading H1 and
titleis omitted, that H1 becomes the Notion page title and is removed from the page body.
CLI
export NOTION_TOKEN=ntn_xxxxx
npx github-to-notion --config notion-sync.yamlUseful flags:
--branch <name>overrides the source branch used in GitHub links.--document <id-or-path>syncs only the selected document. Repeat the flag or pass a comma-separated list.--dry-runreports content and title changes without writing.--forcereplaces the page content even when the canonical markdown already matches.
GitHub Action
name: Sync docs to Notion
on:
push:
branches: [main]
paths:
- "docs/**"
- "README.md"
- "notion-sync.yaml"
workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: your-org/github-to-notion@v1
with:
config: notion-sync.yaml
env:
NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}Action inputs:
configrootbranchdocumentsdry-runforcenotion-token
Link rewriting
Relative links are rewritten against the configured or inferred source branch:
[API](./api.md)->https://github.com/org/repo/blob/main/docs/api.md->https://raw.githubusercontent.com/org/repo/main/docs/img/arch.png[Section](#heading)stays unchanged- absolute URLs stay unchanged
Reference-style links and images are supported too.
Library API
import { runSync } from "github-to-notion";
await runSync({
repoRoot: process.cwd(),
documentSelectors: ["readme"],
});The lower-level loadSyncProject and syncProject exports are available when you want to supply your own Notion client boundary.
Development
npm run typecheck
npm test
npm run build
npm run verifyLicense
MIT
