Projects
Things I've built
Libraries I maintain and testing tooling I built because I needed it, plus the products I've shipped as an engineer on a team. Star and install counts are live from GitHub and npm.
Open source
state-in-url
Stores nested, typed state directly in the URL via React hooks. I built it because I needed a fast, convenient way to preserve state on page reload and share page links.
- React
- TypeScript
- Tailwind
- Next.js
- Remix.js
- react-router
419 2.8k/wk
react-horizontal-scrolling-menu
A reusable horizontal scroll component. TypeScript, well tested, and used in production dashboards I never get to see. Maintained for years across multiple React majors and refactored along the way.
- React.js
- CI/CD
- storybook
- npm
790 95k/wk
test-proxy-recorder
VCR for Playwright - records real API responses once, then replays them deterministically on CI. Covers Next.js SSR, browser, and WebSocket traffic with no backend and no hand-written mocks. I built it because every flaky e2e run traces back to the network.
- TypeScript
- Playwright
- Next.js
- WebSocket
- e2e
- npm
78 76/wk
X-Pat
X-Pat, a browser extension that puts an X account's country in the hover card and the feed, using X's own location API through your existing session. The feed fills in as you scroll without draining the endpoint's rate limit, and accounts can be collapsed, hidden or highlighted by country, organisation, age or bio keyword.
- TypeScript
- Browser extension
- MV3
- Playwright
- Cloudflare Workers
- SQLite

heatmap-analytics
Self-hosted click and hover heatmaps, scroll depth, rage-click detection and ghost-cursor session replay, rendered on the live page. No cookies, no third-party scripts, and a tracker that is 1.7KB gzipped.
- Cloudflare Workers
- D1
- SQL
- TypeScript
- Node.js
- Analytics
llm-queue
A single-worker priority queue for local LLMs, exposed as an OpenAI-compatible HTTP service - so cron jobs, browser extensions and OpenAI clients all share one serialized queue against one model instead of fighting over the GPU.
- Node.js
- TypeScript
- Ollama
- HTTP API
- CLI
- npm
omarchy-last-session
Session restore for Omarchy (Arch Linux with Hyprland): saves the windows you have open and brings them back after a reboot, shutdown, logout or crash, each on the workspace and monitor it was on. Python standard library only, no compositor patches, no extra daemons.
- Python
- Linux
- Hyprland
- Omarchy
- Plugin

Contributions to other projects
Merged pull requests to google/wireit, withastro/docs, withastro/astro and 2 more: fixes and docs accepted into other maintainers' repositories with 100 or more GitHub stars.
All contributionsClient & product work
Closed-source commercial work - the write-ups cover what I owned and what shipped.
Omise - payments merchant dashboard
The merchant-facing dashboard for Omise's payments platform: three years building and maintaining it in React, GraphQL, and styled-components, plus an internal D3.js analytics dashboard and a JavaScript SDK bridging a native mobile wrapper to JS mini-apps.
- React
- GraphQL
- styled-components
- D3.js
- Payments
- SDK

channels.careers
A B2B hiring platform startup. Built the UI to match the design closely, refactored code, adapted it to mobile, and wrote Playwright tests the team actually relies on.
- React.js
- Next.js
- TypeScript
- Playwright
- B2B

Available for full-time remote work in EU timezones, 40 hrs/week.
Get in touch