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

gridmd

v1.0.0

Published

GridMD reference parser, linter and two-way XLSX converter (spec: SPEC.md)

Readme

gridmd

The GridMD reference implementation: a parser + linter and a two-way .gmd.xlsx converter, plus a bounded formula evaluator that verifies cached values (SPEC §6 — writers must never fabricate caches). Strict TypeScript, runs on Bun, published to npm as gridmd.

This is the semantic reference for the cross-language conformance suite (../conformance/): its canonical model dump defines the contract every other implementation (../go, ../rust, ../swift) must match byte-for-byte.

Setup

bun install          # one lockfile (bun.lock), one runtime dep (yaml)

Requires Bun ≥ 1.3. Node ≥ 20 is only needed to run the published package (the built dist/ is plain ESM); development uses Bun to run the .ts sources directly.

Commands

bun test                 # run the suite (bunfig gate: 100% line coverage)
bun run test:coverage    # same, with the coverage table
bun run typecheck        # tsc --noEmit (strict) over src, bin, test
bun run build            # bundle dist/ (JS via bun build, .d.ts via tsc)

# dev tools (run the .ts sources directly; paths relative to js/)
bun run lint:example         # lint ../examples/quarterly-report.gmd
bun run xlsx:example         # → ../examples/quarterly-report.xlsx
bun run roundtrip:example    # gmd → xlsx → gmd, then re-lint
bun run dump <file.gmd>      # canonical conformance dump to stdout

# the CLIs directly (dev)
bun bin/gridmd-lint.ts [--lenient] <file.gmd> …
bun bin/gridmd-dump.ts <file.gmd>              # conformance dump
bun bin/gridmd2xlsx.ts <file.gmd> [-o out.xlsx] [--strict]
bun bin/xlsx2gridmd.ts <file.xlsx> [-o out.gmd]
bun bin/gridmd-calc.ts <file.gmd> …            # verify cached values

Library API

import {
  lint, parseDocument,
  buildWorkbookModel, writeXlsx, xlsxToGridmd, dumpModel,
  verifyCachedValues, createEvaluator,
} from 'gridmd';
import type { WorkbookModel, Sheet, CellContent, Scalar, Diagnostic, LintResult } from 'gridmd';

const { doc, errors } = lint(source);            // parse + validate
const model = buildWorkbookModel(doc);           // → workbook model
const { buffer, report } = writeXlsx(model);     // → .xlsx (Buffer) + fidelity report
const dump = dumpModel(model);                   // → canonical conformance JSON
const { gmd } = xlsxToGridmd(buffer);            // .xlsx → GridMD
const { mismatches, unsupported } = verifyCachedValues(model);

The full model/diagnostic shapes are exported as types (Sheet, Cell, CellContent, Scalar, WorkbookModel, ChartModel, …).

Coverage gate

The bunfig.toml gate enforces 100 % line coverage (bun test fails otherwise). The suite hits every line of src/** — verified via lcov.

Why line coverage and not function coverage? Bun's function-coverage metric has a confirmed false negative: it reports 98.8 % functions for src/calc.ts and blames one anonymous arrow it cannot name (lcov emits no FN/FNDA entry for it). To rule out a real gap, every function and callback in calc.ts was instrumented with a file-based hit marker and the whole suite run — all of them fire. So the code is genuinely 100 %-covered; the 98.8 % is a Bun instrumentation artifact, not a missing test. Line coverage (the metric Bun measures correctly, and the one the cross-language contract cares about) is therefore the gate. This is the one documented coverage exception.

npm publishing

// package.json (already configured)
"exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } }
"bin":     { "gridmd-lint", "gridmd2xlsx", "xlsx2gridmd" }  // → dist/bin/*.js (node shebang)
"files":   ["dist"]
"prepublishOnly": "bun run build && bun test"

bun run build produces dist/index.js (bundled, yaml kept external so consumers dedupe it), dist/bin/*.js (node-runnable CLIs), and the .d.ts type surface. npm publish runs prepublishOnly (build + full suite) first. Consumers that touch the Buffer-typed APIs (writeXlsx, zipRead/zipWrite) need @types/node — standard for a Node library.

CODING_PRACTICES adherence

Applies ~/Dev/bella-team-files/CODING_PRACTICES.md §1 (TypeScript boundary safety): explicit return types on exports; strict + noUncheckedIndexedAccess

  • verbatimModuleSyntax; catch (e: unknown) with narrowing; exhaustive switches with never/throw defaults; no as-casts on untrusted input; the GridMD source is validated by the lint pass before any model is built.

Deliberate divergences

This is a zero-backend polyglot library, not a Next/Nest app, so the Next/Nest-specific rules don't apply. Two intentional, contained divergences:

  1. YAML-derived data is typed as a permissive Meta alias (= any), not a web of speculative interfaces. The SPEC allows x- extension keys and open per-directive shapes, so directive metadata (meta/props/body, frontmatter) enters as parsed YAML and is validated by the lint pass, not the type system. The stable surface — scalars, cells, sheets, the workbook model, diagnostics, the block tree — is fully, strictly typed (src/types.ts), and the byte-identical conformance suite + 100 % line coverage are the real validation. Typing the open YAML fully would have risked the port's byte-for-byte guarantee for no safety gain. See the header of src/types.ts.

  2. The theme-tokens/no-any rule is relaxed only for that YAML surface; everywhere else (the model, XLSX emit/parse, the evaluator) is any-free.

The port's overriding invariant is behaviour-identical, byte-identical output: the four conformance dumps, the example .xlsx, and the round-trip .gmd are all verified byte-for-byte against the pre-migration JS reference.