authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-03-20 01:17:08-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-03-20 14:11:08-07:00
log5b921620c94fade38cd72a34fe2e1d195ef19cb8
treec14a05d2bcc63d21b1adda5578cfb1b8d26e1387
parent704609c6289c855a7653a8bd26a70e159da97959
signaturebadge-check Signed by SSH key SHA256:xbd+BjjhyBfwk7GVoURf9Yx0gzDerHbvYv7SddNWmAs

fix: readme tidying


2 files changed, 23 insertions(+), 4 deletions(-)

README.md+22-3
......@@ -25,16 +25,25 @@ to Streamdown:
2525 as adjacent content changes. This is done to preserve remounts for things like
2626 custom `<a>` tags or other components. (For example, if a custom `<a>` fetches
2727 previewing data and provides a hover card, that card won't flicker).
28- **Better Prediction**: While optimizing edge cases, the prediction system became
29 better than the Streamdown one on accident.
2830- **Headless UI**: No built in styles or components, bring your own CSS to blend
2931 your markdown with your existing theme. `@clo/react-markdown` simply takes in
3032 your existing `unified` pipeline and works off of that.
31- **Easy to Audit**: ~850 lines of TypeScript. Main dependency is [unified].
33- **Easy to Audit**: Only ~1000 lines of modern TypeScript. 4 total files.
3234
3335[Streamdown]: https://streamdown.ai
3436[unified]: https://unifiedjs.com/
3537
3638## Getting Started
3739
40Install off of the [JSR package](https://jsr.io/clo/react-markdown):
41
42```sh
43npx jsr add @clo/react-markdown
44pnpm add jsr:@clo/react-markdown
45```
46
3847```tsx
3948import { Markdown } from "@clo/react-markdown";
4049import remarkGfm from "remark-gfm";
......@@ -70,6 +79,15 @@ export function HelloWorld() {
7079}
7180```
7281
82If you want to play with the example project, which offers a comparison to
83Streamdown and the non-memoized `react-markdown` package.
84
85```
86git clone https://git.paperclover.net/clo/react-markdown
87cd react-markdown
88pnpm demo # auto-install
89```
90
7391## Architecture
7492
7593The `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
89107 it means any places that might have used a reference link may now have to
90108 reflect it.
91109- After all that, a special AST -> React node transform is used that diffs the
92 new ast with the last ast, reusing React nodes whenever possible. This is what
93 prevents most rerenders.
110 new ast with the last ast, reusing React nodes whenever possible. It supports
111 nested children as well as re-ordering top level blocks. This is what prevents
112 most rerenders and is the "secret sauce".
94113
95114All put together, basically nothing rerenders except what actually changed, and the document is beautiful.
package.json+1-1
......@@ -6,7 +6,7 @@
66 "./Predict": "./src/Predict.ts"
77 },
88 "scripts": {
9 "demo": "vite dev",
9 "demo": "pnpm install && vite dev",
1010 "all": "pnpm --parallel fmt && pnpm --stream '/check|test$/'",
1111 "test": "vitest",
1212 "check": "oxlint --react-plugin --vitest-plugin --type-aware --type-check .",