A few things I've built lately started the same way: something got on my nerves, so I made it stop. Here are four of them, what they do, and how they're put together.
QuickDev: one command opens the whole project
Every time I start on a project I open the same terminals, cd into the same folders, run the same commands and launch the same apps. QuickDev is a small Rust CLI that remembers all of that. Describe the project once in a .quickdev.toml, then run quickdev launch from anywhere and everything opens.

- Terminal tabs with working directories and startup commands
- Launches apps, and detects VS Code, Cursor and Zed
- On macOS it can capture the apps you already have open into the config
- Interactive
fzfpickers for adding, removing and launching selectively doctor,validateandprunefor diagnostics, with--jsonfor CI- Shell completion for bash, zsh, fish and PowerShell
It runs on macOS, Linux and Windows, is written in asynchronous Rust, and ships through crates.io, npm and prebuilt binaries. At its peak it reached 530 downloads a week, which is a lot for something I built to scratch my own itch. The code is on GitHub.
Astryn: a command center for the working day
Astryn started as a power client for Linear: issues on a real calendar you can drag to reschedule, list and Kanban views, a Markdown editor with threaded comments, and a dependency graph. Then it grew. It now carries GitHub pull requests, a Slack catch-up board and a cached documentation browser, all in one tabbed window you can split in two.
The Rust core owns everything sensitive. Credentials live in the OS keychain, and every Linear, GitHub, Slack and LLM call runs in Rust behind typed Tauri commands, so the webview never sees a token. SQLite backs a local-first cache with optimistic updates and background sync.
One choice worth calling out: the standup and weekly reports are generated from that cache deterministically first, and only then does an optional prose pass run over any OpenAI-compatible endpoint. The facts survive even when the model does not.











It's built with Tauri 2, Rust, React 19, TypeScript and TanStack Query, and it's at v5.0.1. Source on GitHub.
A local LLM fallback for when the cloud runs dry
Cloud AI tools have quotas, and quotas run out at the worst moments. So I keep a local stack ready to take over: llama.cpp and Ollama running quantized Qwen and Gemma models in the 9B to 27B range.
Most of the work is tuning. Quality, speed and memory pull against each other, and the goal is the balance a consumer machine can actually sustain. It's also where my M.Sc. thesis comes from: adaptive control of local LLM agents on consumer hardware, which is in progress.
It sits nicely beside my Claude Code setup, which warns me as the limits fill up.
This portfolio: a transit map of my career
The site you're reading is a transit map. Each stack I work in is a line, each project or job is a station, and interchanges show where stacks meet. There are seven lines. The map is generated from data, so it works as an accurate index and not as decoration.

Adding a project takes one entry in one data file. It shows up as a row in the work list, a detail page and a station on the map, with no other changes.
The map comes in two forms. A flat SVG paints straight away, and a three.js model on a lit enamel plate loads in idle time as its own chunk. If you prefer reduced motion, have data-saver on, or WebGL fails, you get the flat map. Every page works either way.


Underneath, the layout is plain geometry: rails, 45° bends, bundled tracks at interchanges and year zones. A small scorer picks each label's position by testing it against the tracks, the stations and the other labels. On phones the map takes the full height and you swipe sideways. On a keyboard, 1 to 5 switch pages.

The source is on GitHub as final-portfolio.