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

@markantolang/parser

v0.1.1

Published

Reference implementation of Markanto, a Markdown variant for robust, canonical, agent-ready documents — a tolerant parser, a canonical formatter, and a semantic-AST validator. Zero runtime dependencies.

Readme

@markantolang/parser

Markdown stays nice, and becomes reliable.

The reference implementation of Markanto 0.1.0 — a parser, a semantic-AST validator, and a canonical formatter for a Markdown variant.

Read tolerantly, model strictly, serialise canonically. CommonMark standardises how Markdown is read; Markanto also standardises how it is written. The parser accepts the loose Markdown people actually write, models it in a strict semantic AST, and the formatter serialises exactly one canonical form per meaning. Markanto-specific syntax is designed to degrade gracefully — in a plain Markdown renderer it should lose its meaning, never its readability.

Parsing, validation, canonical formatting, and diagnostics are separate operations with separate result types; resource exhaustion is always distinct from language invalidity.

  • Zero production dependencies. npm install @markantolang/parser pulls nothing else.
  • Deterministic. Forward-only scanning, bounded lookahead, no backtracking over competing interpretations, RE2-compatible expressions only.
  • Runtime-neutral. Node ≥ 18.20 and Bun. The semantic core uses no runtime-specific APIs.

Specification: spec/markanto-spec-v0.1.0.md · Homepage: https://markanto.org

Install

npm install @markantolang/parser

Quickstart

import { parse, format, validate } from '@markantolang/parser';

const source = '# Title\n\nSome **bold** text and a [link](https://example.org).\n';

const parsed = parse(source);
if (parsed.status !== 'ok') {
  // 'invalid'  — not a valid Markanto document (see parsed.diagnostics)
  // 'resource' — a resource budget was exceeded
  throw new Error(`parse: ${parsed.status}`);
}

// parsed.document is the semantic AST (see `src/ast.ts` for its shape).
const formatted = format(parsed.document);
if (formatted.status === 'ok') {
  console.log(formatted.source === source); // true — this input was already canonical
}

console.log(validate(parsed.document).status); // 'ok'

Every operation returns a tagged union — branch on status before reading any payload. There is no thrown error and no inline error node for ordinary failures.

| Operation | Call | status | Payload on success | |---|---|---|---| | Parse surface → AST | parse(source, options?) | ok | invalid | resource | document, annotations | | AST → canonical surface | format(document, budget?) | ok | invalid | resource | source | | Validate an AST | validate(document, options?) | ok | invalid | resource | — | | Check surface canonicality | checkCanonical(source) | canonical | noncanonical | invalid | resource | canonical (the corrected surface) |

parse(source, { strict: true }) accepts only the canonical surface and returns invalid with a noncanonical diagnostic otherwise. Default (strict: false) accepts the documented tolerant surface. parse(source, { errorRecovery: true }) additionally returns a RecoveryDocument (which may hold ErrorBlocks) on invalid input — it never changes the AST of valid input.

Source positions are not fields of AST nodes; when you need them, read the per-result annotations sidecar (parsed.annotations, only present on ok and on recovery results). See docs/PARSER_CONTRACT.md.

CommonMark / GFM import

Converting existing CommonMark or GFM into Markanto is an explicit, lossy operation behind a separate entry point, so the core parser never depends on a Markdown library:

import { importCommonMark } from '@markantolang/parser/commonmark';

const { markanto, diagnostics } = importCommonMark('# Hi\n\nsome _text_\n');

The micromark / mdast packages this subpath needs are optional peer dependencies — install them alongside @markantolang/parser only if you use the subpath. diagnostics is an ordered loss-policy ladder: normalised, resolved, source-structure-loss, semantic-degradation, content-dropped, unrepresentable. The last two are hard-loss conditions suitable for failing an unattended import.

CLI

npx markanto check  <file>            # is the file a valid Markanto document?
npx markanto check  <file> --strict   # …and is its surface exactly canonical?
npx markanto format <file> --stdout   # print the canonical form
npx markanto format <file>            # rewrite the file in place
npx markanto adopt  <file> --stdout   # attach durable identity (see docs/PARSER_CONTRACT.md)

check exits non-zero when the file fails the requested check.

Guarantees

  • One meaning ⇒ one surface. format(parse(s).document) is idempotent, and two surfaces with the same meaning format to the same bytes.
  • Semantic round-trip. parse(format(ast)) reproduces the same semantic AST.
  • Linear time. Target O(n) parsing with a monotonic cursor; the property gate (bun run soak) includes a parser-linearity probe.
  • Portability. The architecture is written to be ported mechanically to safe, idiomatic Rust (docs/PORTABILITY.md).

Documentation

Development

bun run verify        # type check + boundary checks + conformance corpus + full test suite
bun run verify:node   # the portable subset under the supported Node baseline
bun run compat:report # classify the 672 vendored CommonMark 0.31.2 / GFM cases
bun run soak          # 100k seeded documents per stream through the §7.2 laws (heavier gate)
bun run bench         # parse throughput vs marked.lexer (Node; bench:bun for Bun)

Bun is the primary test/runtime environment; Node is the secondary compatibility check. The conformance corpus is JSON and is validated by the same .mjs script under both.

Non-goals

No added syntax, no compatibility aliases, no parser profiles that alter meaning, no raw HTML, no plugin semantics, no heuristic media typing, no generalized recursive containers.

License

ISC © Michael Kortstiege