From 5b921620c94fade38cd72a34fe2e1d195ef19cb8 Mon Sep 17 00:00:00 2001 From: clover caruso Date: Fri, 20 Mar 2026 01:17:08 -0700 Subject: [PATCH] fix: readme tidying --- README.md | 25 ++++++++++++++++++++++--- package.json | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ec314be5112c2e466115b413b6dc08a5a03ab5d5..86e4c00547a42156b147e6b50aa245b9f371d276 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,25 @@ to Streamdown: as adjacent content changes. This is done to preserve remounts for things like custom `` tags or other components. (For example, if a custom `` fetches previewing data and provides a hover card, that card won't flicker). +- **Better Prediction**: While optimizing edge cases, the prediction system became + better than the Streamdown one on accident. - **Headless UI**: No built in styles or components, bring your own CSS to blend your markdown with your existing theme. `@clo/react-markdown` simply takes in your existing `unified` pipeline and works off of that. -- **Easy to Audit**: ~850 lines of TypeScript. Main dependency is [unified]. +- **Easy to Audit**: Only ~1000 lines of modern TypeScript. 4 total files. [Streamdown]: https://streamdown.ai [unified]: https://unifiedjs.com/ ## Getting Started +Install off of the [JSR package](https://jsr.io/clo/react-markdown): + +```sh +npx jsr add @clo/react-markdown +pnpm add jsr:@clo/react-markdown +``` + ```tsx import { Markdown } from "@clo/react-markdown"; import remarkGfm from "remark-gfm"; @@ -70,6 +79,15 @@ export function HelloWorld() { } ``` +If you want to play with the example project, which offers a comparison to +Streamdown and the non-memoized `react-markdown` package. + +``` +git clone https://git.paperclover.net/clo/react-markdown +cd react-markdown +pnpm demo # auto-install +``` + ## Architecture The `Markdown` component is built out of a memoizer which uses the following tricks to improve performance: @@ -89,7 +107,8 @@ The `Markdown` component is built out of a memoizer which uses the following tri it means any places that might have used a reference link may now have to reflect it. - After all that, a special AST -> React node transform is used that diffs the - new ast with the last ast, reusing React nodes whenever possible. This is what - prevents most rerenders. + new ast with the last ast, reusing React nodes whenever possible. It supports + nested children as well as re-ordering top level blocks. This is what prevents + most rerenders and is the "secret sauce". All put together, basically nothing rerenders except what actually changed, and the document is beautiful. diff --git a/package.json b/package.json index 8fd719e6c8971d573d3735a4d7f77aaca1e5b8db..e6737ab9236040db01c2c53e6e9859c5012999e9 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "./Predict": "./src/Predict.ts" }, "scripts": { - "demo": "vite dev", + "demo": "pnpm install && vite dev", "all": "pnpm --parallel fmt && pnpm --stream '/check|test$/'", "test": "vitest", "check": "oxlint --react-plugin --vitest-plugin --type-aware --type-check .", -- 2.54.0