This site uses one functional cookie to keep feature rollouts consistent for you. Nothing is set until you choose. See the privacy notice.
Dev notes
How I turned 10 old jobs into a single interactive page, and the handful of decisions that made it buildable without turning into a museum of dead apps.
Past work rots. The apps have dead backends, retired auth, paid licenses, and client names you can't show. A list of "things I built" is either a wall of dead links or a wall of screenshots. I wanted something you could actually touch.
The originals leaned on MUI, ECharts, AG Grid, a node-graph library, gridstack, a code editor. Pulling all of that in to mimic them would bloat the bundle for a portfolio page, which is exactly the kind of thing the tree-shaking write-up argues against.
recharts already in the tree. The drag-drop dashboard is CSS grid, the node graph is hand-built SVG, the "code editor" is a read-only pre.next/dynamic, so the page ships only the demo on screen, never all 22 at once.?feature= deep links. prefers-reduced-motion drops the animation entirely.ComingSoonDemo placeholder.Update — August 10, 2026
The dual tickers above were written for this page and stayed that way for a while. Two things forced the issue. First, they could not actually reach every chip — the loop scrolled but there was no way to get to items past the fold, so some of the portfolio was unreachable by anything except waiting. That got fixed by pinning the tickers, scrolling the demo area beneath them, and driving the loop from scrollLeft rather than a transform, which makes the same element both the animation and the scroll container instead of fighting between the two.
Once they scrolled properly they were close enough to the ticker on the landing page that keeping two implementations was indefensible, so they moved onto the shared component. That is the sequence I would repeat: make the bespoke thing correct first, then unify. Unifying around a broken shape just spreads the bug.
The drag bugs were the same bug twice. Dragging an NFT between panes and dragging a post between queue columns both failed the same way, because a dragged item rendered inside its source container is clipped by that container the moment it leaves. The fix in both cases is a drag overlay — render the thing being dragged in a layer above the layout rather than in the tree it came from. Worth knowing once, because it is the answer every time.
And a class of bug I keep finding. Side effects had crept into state updater functions here, exactly as they had in the Learn steppers. An updater must be a pure function of previous state; React is allowed to call it twice, and anything with a consequence does not belong in it. Two features, two independent authors of the same mistake, which tells me it is a shape worth watching for rather than a one-off. The referral click tracking moved to the mutation where it belongs, and the Escape handling on the explainer dialog stopped depending on render timing.