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

@kud/ink-markdown

v0.1.1

Published

A high-performance Markdown / code / diff rendering engine for Ink 7.

Downloads

260

Readme

TypeScript Node.js Status MIT

A high-performance Markdown / code / diff rendering engine for Ink 7.

Website · Documentation

Alpha. The rendering path works today: parse a document, lay it out for a width, and scroll a virtualised viewport over it. MarkdownViewport, useMarkdownScroll and the whole core surface are real and covered by tests. Still ahead: syntax highlighting for fenced code (M4), the useMarkdownStream hook, overridable per-block renderers, and performance instrumentation — each is called out where it appears below. The API may still move before 1.0.

Features

Ink apps that display large, code-heavy, streaming documents (AI responses, code review, diffs, source files) hit a wall with naïve Markdown renderers: parse the whole document into a React tree, run Yoga layout over all of it, re-diff the entire output every frame. ink-markdown is designed to keep that cost bounded to the viewport instead:

  • Viewport virtualisation ✅ — only the visible slice is ever composed, so React/Yoga work scales with viewport size, not document size. MarkdownViewport mounts exactly one <Text> whatever the document length.
  • Block-based incremental parsing ✅ — Markdown is segmented into top-level blocks with stable IDs and source hashes, so an edit in one block leaves the others untouched (updateMarkdownDocument).
  • Cached, width-aware layout ✅ — wrapping, Unicode width and styling are computed once per (block, width, theme) and reused until one of those changes, so a terminal resize doesn't force a full relayout.
  • Unified-diff rendering ✅ — hunk headers, additions and deletions are styled from the theme rather than treated as flat text.
  • Syntax highlighting for fenced code ⏳ — planned for M4; code blocks currently render unhighlighted, clipped rather than wrapped.
  • Streaming with a mutable tail ⏳ — the immutable-completed-blocks design is in place, but the useMarkdownStream hook that drives it is not written yet.
  • Overridable block renderers and perf instrumentation ⏳ — designed in prd.md, not yet built.

Where the performance claims come from — a benchmark spike proved the bet before the package was built: parsing a 10,000-line document took ~6.9ms (against a 100ms target), the pre-composed-string render path stayed at a constant ~1.6µs per frame regardless of document size, virtualisation mounted 1 Ink node against 9,167 for a naïve full-tree baseline, and CPU per scroll frame measured ~7.7ms — under Ink's ~26ms repaint throttle, so scroll latency is throttle-bound rather than compute-bound. The shipped engine implements that architecture; the numbers above are the spike's, not a benchmark of the current code.

Install

npm install @kud/ink-markdown

ink-markdown targets Ink 7.x and React 19.x as peer dependencies, and requires Node.js 20+.

Usage

height is a prop, not something the component measures for itself — the caller owns the viewport, so there is no measurement round-trip to get wrong.

import {
  createMarkdownDocument,
  createMarkdownLayout,
  MarkdownViewport,
  useMarkdownScroll,
} from "@kud/ink-markdown"

const Reader = ({ source, width, height }) => {
  const [offset, setOffset] = useState(0)

  // Laying out once and passing `layout` skips the parse on every scroll frame.
  const layout = useMemo(
    () =>
      createMarkdownLayout(createMarkdownDocument(source), source, { width }),
    [source, width],
  )

  useMarkdownScroll({
    totalLines: layout.totalLines,
    height,
    offset,
    onChange: setOffset,
  })

  return (
    <MarkdownViewport
      layout={layout}
      width={width}
      height={height}
      scrollOffset={offset}
    />
  )
}

Pass source instead of layout and the viewport parses and lays out for you — fine for short, static documents, and one prop less to thread.

useMarkdownScroll is optional — it binds j/k, arrows, space, b, g and G. The core owns scrolling primitives (an offset in, lines out), not keybindings, so an app with its own bindings drives scrollOffset directly and ignores the hook.

createMarkdownLayout also takes a theme and a cache — a Map you own and reuse across renders, so a resize re-lays out only the blocks whose width actually changed. layout.reused and layout.computed report how that went.

Streaming (useMarkdownStream), overridable per-block renderers and performance instrumentation are designed but not yet built — see prd.md for the full specification and plan.md for the decisions and spike results behind it.

Development

git clone https://github.com/kud/ink-markdown.git
cd ink-markdown
npm install
npm run build
npm test

Other scripts: npm run build:watch (rebuild on change), npm run typecheck, npm run test:watch.

📚 Full documentation → ink-markdown/docs