I build what I need.
Then I ship it.

Six products live across iOS, Android, and the web. Each one traces back to a real gap in a domain I actually live in — the clinic, the house, or the web.

6 shipped 2 mobile apps 3 Chrome extensions 1 web app

A gap existed in accessible, portable clinical measurement tools. I built to fill it.

WristSkill app menu — Performance Mode, Free Play, View Progress, About the Metrics

WristSkill

iOS · Unity · C#
Live

Wrist proprioception tracking had no lightweight, phone-based option — just bulky lab equipment.

Wrist proprioception assessment for clinicians and patients. Standard goniometers measure angle — WristSkill measures accuracy. Tracks six motion planes per hand with session history and baseline promotion.

Unity 6 C# iOS Firebase
AngleSnap measuring wrist extension during a telehealth visit — 68° reading

AngleSnap

Chrome Extension · Vanilla JS
Live

Clinicians measuring range of motion on screen had no purpose-built tool — a physical goniometer can't measure a screen.

Measure joint angles on any image or video in your browser. Click three points — proximal, joint, distal — instant reading: 55° (125°). All points draggable, nothing stored.

Chrome MV3 Vanilla JS Free

Clinical background Wrist proprioception research Dart-thrower's motion Ulnar-sided wrist pain SMART functional goals

My family needed a better system than a whiteboard.

Problems I kept hitting on the web — AI clutter, weak prompts, pricing games — each got its own fix.

WristSkill Labs assistant chat widget — on-device AI conversation

WristSkill Labs Assistant

On-Device AI · WebLLM + React
Live

Every AI chat widget on the web ships your conversation to a server. This one doesn't have a server to ship it to.

An AI assistant that runs entirely in your browser — a deliberate tradeoff, not a ceiling. A compact 4-billion-parameter model runs on your own device via WebGPU, grounded in this site's content. Conversations never leave your machine; the only thing it ever transmits is a contact request you approve. The compact model — and desktop-first support — are the price of keeping it free to operate and private by design, chosen on purpose. The same architecture runs larger on-device or cloud-hosted models when a project calls for more.

WebGPU Qwen3 4B WebLLM React No server
SlopShield settings panel — priority sites and on-device filter modes

SlopShield

Chrome Extension · TypeScript
Live

AI-generated filler was everywhere — X, Reddit, LinkedIn — and it all looks the same at a glance.

Detect and filter likely AI-generated content while you browse. On-device AI via Transformers.js — no servers, no accounts. Four filter modes from subtle badges to full hide.

TypeScript Transformers.js Preact Free
Promptello mode picker showing assistant categories

Promptello

Chrome Extension · Vanilla JS
Live

Most people get bad AI results because their prompts are vague. Nobody has time to learn frameworks.

Turn rough ideas into structured AI prompts. Side panel picks the right framework automatically and drops the finished prompt into ChatGPT, Claude, Gemini, or Perplexity.

Chrome MV3 Side Panel Gemini Nano Free
Prior Use Estimator input panel — furniture and car parameters declared by the buyer

Prior Use Estimator

Web App · React + Vite
Live

Used furniture and car listings are priced on feelings. Buyers had no data to push back with.

A negotiation aid for buyers of pre-owned furniture and cars. Describe the piece — or the car's odometer — and it produces a research-backed usage estimate with a confidence rating, plus a paste-ready negotiation brief to send the seller.

React Vite Tailwind Free
UnityUnity
C#
Xcode
React
ExpoExpo
Firebase
JavaScript
TypeScript
Chrome
Vite
PreactPreact
Tailwind CSSTailwind
TF.js
Transformers.js
Git
Get in touch

Have a project in mind?

I'm open to collaborations, commissions, and conversations — across any domain I work in.