npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@greyesg/notion-board

v0.1.5

Published

Reusable Notion CLI for tickets + sprints Kanban workflows with incremental sync.

Downloads

274

Readme

@greyesg/notion-board

Reusable CLI for managing a Notion tickets board and sprints table with incremental sync.

CLI bin: notion-board

Install

Install from npm:

npm install -D @greyesg/notion-board

Add a script in your project:

{
  "scripts": {
    "notion:board": "notion-board"
  }
}

Setup

  1. Create .env.local in your project root.
  2. Fill:
    • NOTION_TOKEN
    • NOTION_DATABASE_ID
    • NOTION_SPRINTS_DATABASE_ID
    • optional: NOTION_API_VERSION
    • optional: NOTION_SYNC_SKEW_SECONDS
    • optional: NOTION_ENV_FILE

Starter template:

NOTION_TOKEN=secret_xxx
NOTION_DATABASE_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NOTION_SPRINTS_DATABASE_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NOTION_API_VERSION=2022-06-28
NOTION_SYNC_SKEW_SECONDS=90

Optional config file:

  • Create notion-board.config.json in your project root when you want to pin exact Notion property mappings or default statuses.
  • You can also point to a custom location with NOTION_BOARD_CONFIG=/abs/path/to/notion-board.config.json.

Example:

{
  "tickets": {
    "properties": {
      "title": { "id": "title", "name": "Description" },
      "key": { "id": "_%7DM%3A", "name": "Ticket ID" },
      "status": { "id": "j%3FEB", "name": "Estado" },
      "sprint": { "id": "JYnM", "name": "Iteration" },
      "owner": { "id": "OEN%40", "name": "Assignee" },
      "description": { "id": "xKBx", "name": "Context" },
      "note": { "id": "Fj%5D%3E", "name": "Review Note" }
    },
    "defaults": {
      "createStatus": "Entrada",
      "seedStatus": "Entrada"
    }
  },
  "sprints": {
    "properties": {
      "name": { "id": "title", "name": "Sprint Name" },
      "code": { "id": "%3AoFt", "name": "Code" }
    }
  },
  "settings": {
    "singleSprint": true
  }
}

Env lookup order:

  1. NOTION_ENV_FILE
  2. nearest .env.local walking up from current working directory
  3. package-local .env.local fallback

Config lookup order:

  1. NOTION_BOARD_CONFIG
  2. nearest notion-board.config.json walking up from current working directory

Required Notion schema

Tickets database

  • One title property for the ticket title
  • One key property (rich_text or title)
  • One status property (status preferred, select supported)
  • One sprint property (relation to the Sprints database)

Property names can be custom. The CLI auto-detects property roles by type and common aliases such as Ticket ID, Stage, Iteration, Notes, etc.

Optional properties:

  • Type
  • Priority
  • Owner
  • long-text description/details
  • note/comments
  • Last Synced At
  • Source

Sprints database

  • One title property for the sprint name
  • One code property (rich_text, title, or select) with values like S0, S1, S2

The CLI works with your existing status labels. It does not require Backlog, Todo, In Progress, In Review, or Done.

Write model:

  • one sprint per ticket is the supported write model
  • read/inspect flows can surface legacy rows with multiple sprint relations
  • deep validation and migration commands flag those rows explicitly

Performance model:

  • tickets and sprints snapshots are materialized locally under .cache/
  • once the cache exists, read-heavy commands refresh it with last_edited_time >= watermark - skew
  • use --full when you want to ignore the cache and rebuild it from live Notion
  • generic parallel reads are intentionally not implemented
  • fast full-table reads only happen through explicit sharded filters

First run

Inspect and validate schema/access:

npm run notion:board -- board:inspect
npm run notion:board -- board:validate
npm run notion:board -- board:validate --deep

Then sync:

npm run notion:board -- board:sync --since-last-run
npm run notion:board -- sprints:sync --since-last-run

Large-board bootstrap with sharded reads:

npm run notion:board -- board:validate --deep \
  --read-shard-property Date \
  --read-shard-start 2024-01-01 \
  --read-shard-end 2026-12-31 \
  --read-shard-workers 6

Force a full cache rebuild after manual deletions or board cleanup:

npm run notion:board -- board:validate --deep --full
npm run notion:board -- board:list --full
npm run notion:board -- sprints:sync --full

Daily commands

List tickets:

npm run notion:board -- board:list

List recent changes only:

npm run notion:board -- board:list --delta

List tickets with page IDs or JSON output:

npm run notion:board -- board:list --show-page-id
npm run notion:board -- board:list --json

Create a ticket:

npm run notion:board -- ticket:create --title "Implement auth guard" --sprint S0 --status "Entrada" --type Feature --priority P1 --description "Protect dashboard routes."

Move a ticket:

npm run notion:board -- ticket:move --key S0-001 --status "En curso"
npm run notion:board -- ticket:move --page-id 32caee4a-39a6-8189-90cc-cb8fd56f8ba7 --status "En curso"

Update a ticket:

npm run notion:board -- ticket:update --key S0-001 --status "En revisión" --note "Ready for verification."
npm run notion:board -- ticket:update --page-id 32caee4a-39a6-8189-90cc-cb8fd56f8ba7 --status "Done"

Create and manage sprints explicitly:

npm run notion:board -- sprint:create --code S7 --name "Sprint 7 - Mobile polish"
npm run notion:board -- sprint:update --code S7 --name "Sprint 7 - Mobile and analytics polish"
npm run notion:board -- sprint:rename --code S7 --name "Sprint 7 - Final polish" --new-code S8

Seed from a markdown plan:

npm run notion:board -- sprints:seed --from <path-to-plan.md> --sprint S0..S6
npm run notion:board -- board:seed --from <path-to-plan.md> --sprint S0..S6 --initial-status "Entrada"

Legacy-safe migrations:

npm run notion:board -- migrate:keys --dry-run
npm run notion:board -- migrate:keys --apply
npm run notion:board -- migrate:keys --sprint S0 --apply --overwrite

npm run notion:board -- migrate:sprints --from-property "Legacy Sprint" --match code --dry-run
npm run notion:board -- migrate:sprints --from-property "Legacy Sprint" --match name --apply

Bulk apply acceleration:

npm run notion:board -- migrate:keys --apply --concurrency-write 3
npm run notion:board -- migrate:sprints --from-property "Legacy Sprint" --apply --concurrency-write 3
npm run notion:board -- board:seed --from product/plan.md --concurrency-write 3

Sharded read flags:

  • --read-shard-property <property-name|created_time>
  • --read-shard-start <YYYY-MM-DD>
  • --read-shard-end <YYYY-MM-DD>
  • --read-shard-workers <n>

Write concurrency flag:

  • --concurrency-write <n>

Cache rebuild flag:

  • --full

Migration defaults:

  • preview-only unless --apply is passed
  • fill-only unless --overwrite is passed
  • page targeting supported with --page-id

Safety

  • ticket:move and ticket:update use read-before-write.
  • Conflict detection uses last_edited_time.
  • ticket:create and ticket:update --sprint do not auto-create sprint rows.
  • If a sprint row is missing, create it deliberately with sprint:create or sprints:seed.
  • board:inspect --deep and board:validate --deep surface missing keys, missing sprint relations, multi-sprint rows, and unknown sprint relations.
  • cache-backed commands print whether they used a cache hit or miss, whether the run was a full bootstrap or delta refresh, and any shard retry/split stats
  • use --full after manual deletions, permission changes, or large cleanup passes so stale cached rows are dropped immediately
  • If the CLI cannot infer a default status safely, it fails and asks you to pass --status or --initial-status.
  • Use --force only when you explicitly want to override conflict protection.

Recommended large legacy-board flow:

  1. Build or refresh cache with board:validate --deep or board:list.
  2. Stage or infer sprint mapping outside the CLI.
  3. Run migrate:sprints --dry-run.
  4. Run migrate:sprints --apply --concurrency-write 3.
  5. Run migrate:keys --dry-run.
  6. Run migrate:keys --apply --concurrency-write 3.

AGENTS.md Guidance

Suggested snippet for repos using this package:

- This repo uses `@greyesg/notion-board` to inspect and manage the linked Notion tickets/sprints databases.
- Before any Notion write operation, run `npx notion-board board:inspect` or `npx notion-board board:validate`.
- Prefer `--page-id` for repair/migration work on legacy boards and `Key` for normal day-to-day collaboration.

Local development

Inside this package repo:

npm install
npm test
npm run build
npm pack