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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@textcortex/jsondoc

v0.2.0-alpha.7

Published

JSON-DOC TypeScript implementation

Readme

JSON-DOC TypeScript Implementation

A TypeScript implementation of JSON-DOC, a standardized format for storing structured content in JSON files, inspired by Notion's data model.

Features

  • Programmatically Generated Types: All TypeScript interfaces are automatically generated from JSON schemas
  • React Renderer: Complete React component library for rendering JSON-DOC content
  • Rich Content Support: Supports all major block types including paragraphs, headings, lists, tables, images, and more
  • Recursive Rendering: Handles nested blocks at arbitrary depth
  • Notion-like Styling: CSS styling inspired by Notion's visual design

Installation

npm install @textcortex/jsondoc

Usage

Basic React Rendering

import React from "react";
import { JsonDocRenderer } from "@textcortex/jsondoc";
import * as fs from "fs";
import * as JSON5 from "json5";

// Load JSON-DOC data (with comment support)
const pageData = JSON5.parse(fs.readFileSync("document.json", "utf-8"));

// Render the document
function App() {
  return (
    <div>
      <JsonDocRenderer page={pageData} />
    </div>
  );
}

Individual Block Rendering

import React from "react";
import { BlockRenderer } from "@textcortex/jsondoc";

function MyComponent({ block }) {
  return (
    <div>
      <BlockRenderer block={block} depth={0} />
    </div>
  );
}

JSON-DOC Viewer (Browser)

View any JSON-DOC file directly in your browser with a single command:

# View a JSON-DOC file
npm run view path/to/your/document.json

# Example: View the test document
npm run view ../schema/page/ex1_success.json

This will:

  1. Start a local server at http://localhost:3000
  2. Automatically open your browser
  3. Render the JSON-DOC file with full styling
  4. Support all block types including nested structures

The viewer includes:

  • Live rendering of all supported block types
  • Notion-like styling with responsive design
  • Automatic browser opening for convenience
  • File information in the header (filename, block count)
  • Comment support using JSON5 parsing

Supported Block Types

The renderer supports all major JSON-DOC block types:

  • Text Blocks: paragraph, heading_1, heading_2, heading_3
  • List Blocks: bulleted_list_item, numbered_list_item
  • Rich Content: code, quote, equation
  • Media: image (both external URLs and file references)
  • Layout: table, table_row, column_list, column
  • Interactive: to_do, toggle
  • Utility: divider

Rich Text Features

Rich text content supports:

  • Formatting: Bold, italic, strikethrough, underline, code
  • Colors: All Notion color options
  • Links: External links with proper target="_blank"
  • Equations: Inline mathematical expressions

Development

Setup

# Install dependencies
npm install

# Generate TypeScript types from JSON schemas
npm run generate-types

# Build the project
npm run build

# Run tests
npm test

# View example JSON-DOC file in browser
npm run view ../schema/page/ex1_success.json

Testing

The test suite includes:

# Run all tests
npm test

# Tests cover:
# - JSON utility functions (loadJson, deepClone)
# - Example file loading with comment support
# - Block type detection and validation

The tests verify:

  • ✅ JSON loading and parsing functionality
  • ✅ Deep cloning of complex objects
  • ✅ Loading of the comprehensive example file (47 blocks, 16 types)
  • ✅ Block type enumeration and structure validation

Project Structure

  • src/models/: TypeScript type definitions (generated from schemas)
  • src/renderer/: React components for rendering JSON-DOC
  • src/utils/: Helper functions
  • tests/: Test suite

Example Data Structure

JSON-DOC uses a hierarchical structure similar to Notion:

{
  "object": "page",
  "id": "page-id",
  "properties": {
    "title": {
      "title": [
        {
          "type": "text",
          "text": { "content": "Document Title" }
        }
      ]
    }
  },
  "children": [
    {
      "object": "block",
      "type": "paragraph",
      "id": "block-id",
      "paragraph": {
        "rich_text": [
          {
            "type": "text",
            "text": { "content": "Hello, world!" },
            "annotations": {
              "bold": true,
              "color": "blue"
            }
          }
        ]
      },
      "children": []
    }
  ]
}

React Component Architecture

JsonDocRenderer
├── Page (icon, title, properties)
└── BlockRenderer (recursive)
    ├── ParagraphBlockRenderer
    ├── HeadingBlockRenderer
    ├── ListItemBlockRenderer
    ├── CodeBlockRenderer
    ├── ImageBlockRenderer
    ├── TableBlockRenderer
    ├── QuoteBlockRenderer
    ├── DividerBlockRenderer
    ├── ToDoBlockRenderer
    ├── ToggleBlockRenderer
    ├── ColumnListBlockRenderer
    └── EquationBlockRenderer

Key Features

  1. Recursive Rendering: All block renderers support children blocks with proper nesting
  2. Type Safety: Full TypeScript support with generated types
  3. Accessibility: Proper ARIA attributes and semantic HTML
  4. Responsive Design: Mobile-friendly layout with responsive columns
  5. Interactive Elements: Toggle blocks can be expanded/collapsed, to-do items show state

CSS Classes

The renderer uses Notion-inspired CSS classes for styling:

  • .json-doc-renderer - Main container
  • .notion-selectable - Individual blocks
  • .notion-text-block, .notion-header-block - Block types
  • .notion-list-item-box-left - List item bullets/numbers
  • .notion-table-content - Table containers
  • .notion-inline-code - Inline code formatting

License

MIT

Configuration

Release workflow

We use bumpp to automatically bump package.json and lock files, create git tags and commits

  1. Run:
 npx bumpp
  1. You should see:

4 Commits since the last version:

5217cd1   : update readme
7a3c03d   : Expose page delimiter
e2791a4   : Merge branch 'main' of github.com:textcortex/JSON-DOC
b7b30c1   : Make more typesafe

✔ Current version 0.2.0-alpha.3 ›          next 0.2.0-alpha.4

   files package-lock.json
         package.json
  commit chore: release v0.2.0-alpha.4
     tag typescript-v0.2.0-alpha.4

    from 0.2.0-alpha.3
      to 0.2.0-alpha.4

You can choose a different version from the list or create new one. But bumpp is smart enough to use appropriate next version.

  1. Verify and confirm
  2. Push commit and tag
git push --follow-tags
  1. The new tag will trigger a release on github actions.
  2. Go to github and create release using the new tag. Make sure you set the correct previous tag prefixed with typescript-v

Todos

  • [x] setup eslint

  • [x] improve tsconfig

  • [x] setup lint staged and husky

  • [x] setup prettier

  • [x] standardize styling (css)

  • [x] fix styling for elements

    • [x] headings
    • [x] paragraph
    • [x] code
    • [x] table
    • [x] to-do items
    • [x] equation
    • [x] image
    • [x] blockquote
  • [x] fix ts and eslint errors in these dirs and remove from ignore list of ts and eslint

        "**/generated/**",
        "src/serialization/**",
  • [x] add counter for numbered lists

  • [x] setup up bumpp: https://www.npmjs.com/package/bumpp

  • [ ] migrate test runner to vitest

  • [x] move vite app to typescript root examples dir

  • [ ] setup monorepo tooling

  • [ ] fix model generation for Image and RichText, then type renderers

  • [x] use katex or similar package for equations

  • [x] add error boundry

  • [x] add page title highlighting

  • [ ] validate page prop somehow. not clear how to do yet. we can't use the /schema because it's HUGE and also because it's outside of /typescript. Will need to think about this.

maybe do something like this?

import type { Page } from "../models/generated/page/page";
import { isPage } from "../models/generated/essential-types";

export function validatePage(obj: unknown): obj is Page {
  console.log("isPage(obj) ", isPage(obj));
  return (
    isPage(obj) &&
    typeof (obj as any).id === "string" &&
    Array.isArray((obj as any).children)
  );
}

export function validatePageWithError(obj: unknown): {
  valid: boolean;
  error?: string;
} {
  if (!isPage(obj)) {
    return { valid: false, error: "Not a valid page object" };
  }

  if (typeof (obj as any).id !== "string") {
    return { valid: false, error: "Page id must be a string" };
  }

  if (!Array.isArray((obj as any).children)) {
    return { valid: false, error: "Page children must be an array" };
  }

  return { valid: true };
}

will require us to write a validator and we won't benefit from the defined schema jsons.

  • [ ] make error boundary catch errors in JsonDocRenderer.tsx body