NotCMS makes it easy to create a CMS, from Notion. It provides a type-safe TypeScript SDK to interact with Notion databases as your content backend.
- 🛡️ Type Safety: Fully typed queries and responses using TypeScript
- 🎯 Simple API: Clean and intuitive API for fetching content
- 📝 Notion as Backend: Use Notion's user-friendly editor for content creation
- 🔄 Framework Agnostic: Works with any JavaScript framework (Next.js, React, Vue, etc.)
- 🛠️ CLI Tools: Includes the NotCMS CLI for project setup, browser login, and schema management
npm install notcmsThe CLI is included in notcms; no separate CLI package is required. Replace deprecated npx notcms-kit <command> usage with npx notcms <command>.
Run the CLI directly with npx:
npx notcms initThis creates notcms.config.json. If credentials are missing, it opens browser
login and saves NOTCMS_SECRET_KEY and NOTCMS_WORKSPACE_ID to .env.local.
It ensures notcms is both a direct dependency and available to the project,
offering either the detected package manager's install command or an add
command without replacing an existing dependency spec. It then pulls the
schema and prints a runnable first query example.
Run the standalone pull command whenever your Notion database schema changes:
npx notcms pullThis fetches your database schema from NotCMS and regenerates the configured TypeScript file.
For reference, the generated schema will look something like this:
// src/notcms/schema.ts
import { Client } from "notcms";
import type { Schema } from "notcms";
export const schema = {
blog: {
id: "your_notion_database_id",
properties: {
title: "title",
description: "rich_text",
published: "checkbox",
thumbnails: "files",
// Run notcms pull again when properties are updated
},
},
} satisfies Schema;
export const nc = new Client({ schema });import { nc } from "./notcms/schema";
// List all blog posts
const [pages] = await nc.query.blog.list();
// Get a specific blog post
const [page] = await nc.query.blog.get("page_id");
// Handle errors
const [data, error] = await nc.query.blog.list();
if (error) {
console.error("Failed to fetch blog posts:", error);
}The SDK and CLI now ship together in notcms. Update old dependency specs
explicitly: init preserves an existing SDK version rather than upgrading it.
npm uninstall notcms-kit # Only if it is a project dependency
npm install notcms@latest
npx notcms pull
npx notcms pull --checkKeep notcms.config.json and your server-side credentials. Replace old
notcms-kit init / notcms-kit pull scripts with notcms init / notcms pull.
Regenerate the schema and typecheck your application before deploying an upgrade;
this is especially necessary for prerelease SDKs such as 0.0.12-development.
See the migration checklist for package-manager equivalents,
CI usage, and compatibility checks.
Check out these examples to get started quickly:
-
Publication, language and stable URL recipes for blogs and release notes
Runnable example source lives under examples/.
If you see errors like "secretKey is required" or "workspaceId is required", make sure:
- Your environment variables are correctly set
- You're using the correct variable names (
NOTCMS_SECRET_KEYandNOTCMS_WORKSPACE_ID) - Your environment variables are being loaded properly
If you encounter schema-related errors:
- Make sure your Notion database IDs are correct
- Verify that the property types match what's in your Notion database
- Try running
npx notcms pullto regenerate your schema
We welcome contributions! Please see our Contributing Guide for details.
Note: This project uses Changesets for version management. When making changes that should be released, please run pnpm changeset to create a changeset describing your changes.
This project is organized as a monorepo with multiple packages:
packages/notcms: MIT Licensepackages/notcms-kit(deprecated): MIT Licenseexamples/nextjs-simple-blog-template: MIT License
See individual directories for specific license details.
Keep generated types in sync with PR and scheduled schema checks.
Build a blog with the Astro guide.