Things I made.
Most of these began because I wanted something to exist and it did not. A few grew into
libraries with users I have never met; the rest stayed small and quietly useful. Even this site
All of these are mine end to end, not mockups or tutorials I followed along with. The bugs I fixed inside other people's code live on the open source page instead.
Libraries & tools
Learn more
@friendofsvelte/tipex
425 stars, maintained since 2023
Tiptap Prosemirror Svelte
I wanted a rich-text editor for SvelteKit that looked finished the moment it was installed. TipTap and ProseMirror handle the document model; everything above them is mine.
- Took TipTap rather than hand-rolling a ProseMirror layer, so I inherited its extension system and only had to own the Svelte side.
- Ship the styling inside the package instead of leaving it to whoever installs it, which is the whole reason it looks done out of the box.
- Rewrote the control system and floating menu for Svelte 5 runes rather than patching the old reactivity around them.
Worked with
bluepuma77 raised five issues, starting with missing CSS in the install instructions
lgrkvst raised four issues on default buttons, focus stealing and the placeholder
digitaldrreamer reported a broken TipTap peer dependency on install
zulienr reported control buttons not rendering, including on Safari
ikshyza found a build where only one version shipped its CSS
robishx asked for background props and a way to drop the focus ring
lalilaloe hit an error using it in a PWA outside SvelteKit
MihaelBercic asked how Enter and Shift+Enter should behave
kinderhead found that default extensions could not be replaced +20
bluepuma77 traded twenty-one messages across their five issues
lgrkvst worked through four issues on the controls and focus behaviour
MihaelBercic turned their question on Enter and Shift+Enter into the docs
Ayush-Tripathy merged their autofocus prop- answered 38 of 40 reporters, closed all 40
Learn more
Svelicon
21 stars, CLI, v2 in 2025
Node.js TypeScript Svelte 5
Every Svelte project I start needs icons, and the libraries I tried either fetched them at runtime or shipped the whole set. I wrote a CLI that puts the icons into the project as real components.
- Generate typed components ahead of time, so icons cost nothing at runtime and a wrong name fails at compile.
- Made it validate tsconfig path mappings while generating, because a broken mapping is the kind of thing you find much later.
- Emit JavaScript or TypeScript depending on the project rather than forcing my preference on it.
Worked with
Learn more
@friendofsvelte/mermaid
36 stars, Svelte 5, since 2025
Svelte 5 TypeScript
I needed Mermaid diagrams on a server-rendered SvelteKit site, and the wrappers I found either broke during SSR or pulled mermaid.js into the first load. So I wrote the component I wanted.
- Load mermaid.js behind a dynamic import so it never reaches the server bundle.
- Hand back a snippet on parse errors instead of throwing, because a bad diagram in someone's content should not take the page down.
- Covered it with Playwright end to end, since the failure I cared about only shows up in a real browser.
Learn more
@friendofsvelte/state
39 stars, Svelte 5, since 2025
Svelte 5 TypeScript
Runes gave me reactivity but not persistence, and I kept rewriting the same localStorage glue in every project. This is that glue written once, typed.
- Put definition, persistence and cross-component sync in a single class, so there is nothing else to learn.
- Made the storage backend a constructor argument rather than a separate API, so moving from local to session is one word.
- Held it to zero dependencies beyond Svelte, because a persistence helper should not own your bundle.
Worked with
Learn more
SEOrd - SEO Analyzer
50 stars, rebuilt for 2.0 in 2026
Node.js TypeScript JavaScript
I had a hard time finding a decent SEO analyser for Node, so I wrote one. For 2.0 I rebuilt it as a rule engine rather than the pile of checks it had grown into.
- Turned 22 checks into individually disableable rules, so the score can be explained rather than just produced.
- Weighted each rule and exposed the breakdown, because a number nobody can account for is not something you can act on.
- Kept it synchronous and down to one dependency, so it drops into a build step without ceremony.
Worked with
Learn more
Fiverr Scraper API
84 stars, 2021 to 2024
Python Web Scraping
I needed Fiverr gig and profile data as structured JSON and there was no clean way to get it, so I wrote the library and put it on PyPI. Seven people have filed issues against it since.
- Return both parsed JSON and the raw soup, so callers can take my parsing or ignore it entirely.
- Wired in proxy and ScraperAPI support so people can route around rate limits without forking it.
- Kept install to one pip package, because anything harder and people just copy the file.
Worked with
ruizuo11 reported profile scraping returning nothing
mubashardev reported a NoneType error in the parser
south1907 reported the scraper silently failing
MatteoSchifano traced an UnboundLocalError to the breadcrumb parser
toffuffee reported a NoneType error on findChild
jayvs6341 reported another NoneType case
wuchuanshiqi asked how profile_scrape is meant to be used
Learn more
notify
Go over D-Bus, 2025
Go D-Bus
I wanted my own Go scripts to raise desktop notifications on Linux without dragging in a desktop framework, so I wrote a thin layer over D-Bus.
- Bound action buttons straight to Go functions, so a notification can run code rather than only appear.
- Chose struct configuration over a builder chain, because the whole thing is one call and a chain would be ceremony.
- Defaulted to freedesktop sound names so it behaves like everything else on the desktop.
Frameworks
Learn more
Fymo
2025 - Present, Python Framework
Python Svelte 5 esbuild
I got tired of maintaining a frontend repo, a backend repo, and an API layer whose only job was to let the two talk. Fymo renders real Svelte 5 from Python, in one repo and one deploy.
- Compile Svelte once at build time and keep a long-lived Node process for rendering, so nothing compiles per request.
- Borrowed SvelteKit's remote functions so the frontend calls typed Python directly and I never write an API layer again.
- Generate the auth into your project as plain code you can read and delete, rather than hiding it inside the framework.
- Ships as one WSGI app, because not deploying two things was the entire point.
Learn more
Djapy
120 stars, 507 commits since 2023
Django Pydantic Swagger
Django REST Framework kept asking me to write serializers for things Django already knew. Djapy uses type hints as the contract instead: a decorator, a return type, done.
- Made the function signature the schema, so there is no second place to keep in sync.
- Kept plain Django decorators like cache_page working, because a framework inside a framework was the thing I was trying to avoid.
- Generate Swagger from the same annotations, so the documentation cannot drift away from the code.
Worked with
Microturbine merged their fix for reparsed schema data
philrdubois fixed the Swagger bug they found- three more contributors
Learn more
Django + SvelteKit Template
72 stars, 2024 to 2025
Django SvelteKit TypeScript
Every time I paired Django with SvelteKit I rebuilt the same plumbing. I solved it once properly and made that the starting point instead of doing it again.
- Got session auth working through server-side rendering, which is the part that breaks first and costs the most to debug.
- Bridged Django messages into Svelte toasts so the backend keeps owning the wording.
- Fed server-side validation errors back into form state rather than duplicating the rules in the frontend.
Worked with
Products
Learn more
Webmatrices
March 2020 to 28 July 2026
Django/Djapy SvelteKit
I have run Webmatrices since 2020: a community where bloggers, publishers and freelancers bring AdSense, SEO and coding problems and get answers from people who have had them.
- Built its APIs on djapy, my own framework, so I was the first person to live with its mistakes.
- Answer and moderate it myself, which means I hear about a broken feature from a member before any dashboard tells me.
- Kept it running for six years, which is a different discipline from launching something.
Learn more
SuperMCP
Tauri desktop app, Rust and Svelte 5, 2026
Rust Tauri Svelte 5
Every MCP server I tried wanted API keys and an OAuth dance for sites I was already signed into. This one borrows the Chrome session that is already open, so Claude, Cursor and Windsurf can read Reddit, X, LinkedIn and the rest without me handing anything over.
- Wrote the worker in Rust as a single static binary and gave every AI client its own process, so one client cannot take another down.
- Emulated Chrome's TLS fingerprint for the sources that answer plain HTTP and only drove a real headless browser for the ones that need a session, because the second costs seconds and the first does not.
- Had every worker append to one activity log that the desktop shell tails, so you can watch which client is reading which source as it happens.
- Ships as a signed installer, because the people who want this are not going to build a Rust workspace.
Learn more
Deviser Club
97 stars, 389 commits in six weeks
Ruby on Rails 7
I wanted to know whether an open source Medium alternative could put authors in charge without getting complicated. Simple beats complex was the whole bet, and I built it on Rails 7 to find out.
- Kept the data model deliberately small, because every feature I skipped was one an author would not have to think about.
- Ran it in the open from the first commit, which is why other people's patches ended up in it.
- Wrote 389 commits in six weeks and then stopped, because I had the answer and it was not going to be a product.
Worked with
Learn more
SatzMaster
July 2025 to August 2025
Next.js React Tailwind CSS
I am learning German and wanted drilling rather than flashcards, so I built three modes I keep coming back to: transcribing sentences, building them from keywords, and reflex drills on grammar patterns.
- Made typing the input, because recognising a correct sentence and producing one are not the same skill.
- Graded every mode A1 to C1, from articles and simple verbs up to subjunctive and passive, so it stays useful as I improve.
- Added timed sprints and a twenty sentence marathon, since the thing I am bad at is grammar under time pressure.
Learn more
Speed Clicking
Browser game, 2022
Next.js Tailwind CSS
My fourteen year old brother plays Minecraft and wanted the clicking trainer he used to do more. I asked why I should not just build it, so I did, and shipped what he asked for.
- Built the features he actually named: fullscreen, a much bigger click area, and a dark mode I threw in.
- Took the spec from someone who would use it daily rather than deciding for him what a good trainer looked like.
- Left it finished once it did what he wanted, instead of finding reasons to keep going.
