Skip to content
GitHubnpm

Notion CMS Adaptor

Type-safe schema definitions, automatic type inference, and convenient query functions for using Notion as your CMS.
// Define schema, get full type inference
const schema = createDBSchemas({
  posts: {
    _id: metadata("id"),
    title: title().plainText(),
    tags: multi_select().stringEnums('tech', 'life'),
    status: status().stringEnum('draft', 'published'),
  },
});

// Query with typed results
const posts = await client.query('posts');
// posts: { _id: string, title: string, tags: ('tech' | 'life')[], status: 'draft' | 'published' }[]

Type-Safe

Define your Notion database schema and let TypeScript infer the types for you. No more guessing what properties exist.

Built on Official SDK

Uses the official @notionhq/client (v5.4.0+) under the hood, ensuring compatibility and reliability.

Auto-Discovery

Give only the ID of the root page, and the framework discovers all databases residing under it automatically.

Flexible Conversions

Pre-defined handlers for common conversions, with full customization support when you need it.

Mutations Support

Full support for creating, updating, and deleting entries with type-safe input validation.

Minimal Footprint

Only necessary wrapper around the Notion API while exposing official structures like RichTextItemResponse.

npm install notion-cms-adaptor
# or
yarn add notion-cms-adaptor
# or
pnpm install notion-cms-adaptor
# or
bun add notion-cms-adaptor
import { createDBSchemas, createNotionDBClient, metadata, title, multi_select, status } from 'notion-cms-adaptor';

const dbSchemas = createDBSchemas({
  posts: {
    _id: metadata("id"),
    title: title().plainText(),
    tags: multi_select().stringEnums('tech', 'life'),
    status: status().stringEnum('draft', 'published'),
  },
});

const client = createNotionDBClient({
  notionToken: process.env.NOTION_TOKEN!,
  autoDetectDataSources: { pageId: process.env.NOTION_CMS_PAGE_ID! },
  dbSchemas,
});

const posts = await client.query('posts', {
  filter: { property: 'status', status: { equals: 'published' } },
});