diff --git a/src/pages/log.mdo b/src/pages/log.mdo
index 4469e9cda08e6f670318cfab3686e32c68419537..0b3fcff0aa62ea751b366917d10b99144b80d827 100644
--- a/src/pages/log.mdo
+++ b/src/pages/log.mdo
@@ -16,7 +16,8 @@ static const repo = "${repo}";
[ts lie detector]: https://git.paperclover.net/clo/ts-lie-detector
[evil inc]: https://evil.inc/
[history of japan reanimated]: /history-of-japan-reanimated
-[react mutation]: /history-of-japan-reanimated
+[react mutation]: http://jsr.io/@clo/react-mutation
+[react markdown]: http://jsr.io/@clo/react-markdown
[HOTEWIG reanimated]: /hotewig-reanimated
[clover creative control]: https://git.paperclover.net/clo/creative-control
[markodown]: https://git.paperclover.net/clo/markodown
@@ -29,6 +30,83 @@ static const repo = "${repo}";
these are like mini blog posts, but more in generally just what the heck i'm up to.
+## 2026-03-20
+
+tags: [react markdown]
+
+i published a new library named `@clo/react-markdown`. originally, i wanted to
+have my own version of the `streamdown` package from vercel. but i didn't
+realize how much of a loser company they all are. i wasn't even trying and i
+made a library like a hundred times better and simpler than theres. because of
+the awesome success here, instead of calling mine "memo markdown", i just said
+"yea, this covers every markdown use case for react" and called it React Markdown.
+
+you can install it from the JSR:
+
+```sh
+npx jsr add @clo/react-markdown
+pnpm add jsr:@clo/react-markdown
+```
+
+there are two main features that i deliver on:
+
+- predicting close tokens for sequences like `hello **world`, appending `**`
+ - streamdown has this too, but many many cases are not considered. while
+ theirs is extensible and mine isn't, i don't think you'll need to extend
+ my markdown predictor.
+- component memoization. all block and inline components will preserve their
+ state, even 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).
+
+copying some architecture notes from the readme, the memoizer is performant
+from the following tricks:
+
+- Using proper `React.memo()` calls. Obviously.
+- Prediction is implemented in a stateful way that only parses the tail end of
+ the document, marking how much of the document is stable and where possible
+ incomplete syntax may live. Since prediction only applies at the end, changing
+ text midway through can invalidate the whole predictor.
+- Separate the parsed document into "blocks", noting the source location of
+ where each block lives.
+- Only start parsing after the first changed character, rounded to the nearest
+ block. In the append-only stream, this essentially means the last two blocks
+ are the only things being re-parsed.
+- Similarly, run AST transforms only on the changed data. This step has a couple
+ of slow paths for when reference link definitions are added or edited, since
+ 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. It supports
+ nested children as well as re-ordering top level blocks. This is what prevents
+ most rerenders and is the "secret sauce".
+
+## 2026-03-18
+
+tags: [progress.ts]
+
+laser hair removal is awesome btw. organizing things at home slowly. more work
+on the progress library, trying to handle every edge case possible for the log
+widget system.
+
+when it is done, a code snippet like this will work.
+
+```ts
+using node = progress.start("some action");
+for await (const token of stream) {
+ // correctly interweave progress TUI with partial log lines
+ process.stderr.write(token);
+}
+```
+
+the log system injects into `process` to ensure it plays nice, but there is
+only a fast path on stdout (since the main log messages uses stdout). stderr
+gets to use the crazy `getDrawLock` API i'm cooking up internally.
+
+after all of this works and is reliable, there are some more things i have to
+tidy, but then the progress blog post can be written and reviewed for realsies.
+
## 2026-03-16
just chilling. at work i replaced `bun install` with `pnpm`. pretty peak. in the