Portfolio

Web applications, native Apple apps, distributed systems, and developer tools I've built.

Web Apps

SaaS products running in production, built on Nuxt, Vue, and Node.js.

AccessHawk website screenshot

AccessHawk

Web Application

Automated WCAG scanning. Each scan opens the page in a real browser with Playwright, runs Lighthouse, then has an AI model review the screenshot, accessibility tree, and HTML. Every issue is boxed on an annotated screenshot with its WCAG criterion and a suggested fix. Scans run on A11yHawk, the open-source engine I extracted from AccessHawk, behind a BullMQ queue that also runs scheduled and CI-triggered scans. The interface is built for low-vision and keyboard users: high-contrast black on white, the Atkinson Hyperlegible Next typeface, a bright yellow focus style, and severity marked by shape and text as well as color.

  • Nuxt 4
  • TypeScript
  • MongoDB
  • Redis
  • BullMQ
  • Playwright
  • Polar.sh
  • OpenRouter
  • Doppler
  • Railway
SereneReader website screenshot

SereneReader

Web Application

A real-time RSS platform with BullMQ background jobs, Server-Sent Events for live updates, and a custom theming engine. Localized into 13 languages with complete message coverage, per-locale plural rules, and locale-specific date and currency formatting. Native iPhone, iPad, Mac, and Apple Watch apps keep feeds, folders, read state, and Focus Mode in sync with the web app.

  • Nuxt 4
  • TypeScript
  • i18n (13 locales)
  • Swift
  • SwiftUI
  • MongoDB
  • Redis
  • BullMQ
  • Polar.sh
  • Resend
  • Doppler
  • Railway
MyPetDay website screenshot

MyPetDay

Web Application

Household pet care tracking, built mobile-first. As solution architect and lead developer I owned the architecture, the Railway infrastructure, security, MongoDB query performance, and media storage on AWS S3.

  • Nuxt 4
  • TypeScript
  • MongoDB
  • Polar.sh
  • AWS S3
  • Tailwind CSS
  • Doppler
  • Railway
SPConnector website screenshot

SPConnector

Web Application

Multi-tenant print routing for e-commerce fulfillment: real-time WebSocket delivery, rules that send each job to the right printer, and AES-256-GCM encryption for customer data. Integrates the Shippo and PrintNode APIs, with a load-balanced queue built for high order volume.

  • Vue.js
  • Express.js
  • MongoDB
  • Redis
  • Polar.sh
  • Resend
  • Tailwind CSS
  • Doppler
  • Railway

Apple Apps

Native apps for Apple platforms, built in Swift and SwiftUI.

SereneReader app artwork: the mint RSS mark on a dark background

SereneReader

  • iPhone
  • iPad
  • Mac
  • Apple Watch

The native client for the SereneReader platform: one Swift 6 codebase covering iPhone, iPad, Mac, and Apple Watch. Mutations write to a local SwiftData store first and replay from a queue when connectivity returns, so starring and marking read work offline, while a long-lived Server-Sent Events connection reconciles state with the web app in real time. Focus Mode, the five hand-tuned themes, and full keyboard navigation on iPad and Mac came across with it.

  • Swift 6
  • SwiftUI
  • SwiftData
  • watchOS
  • WKWebView
  • Server-Sent Events
  • Keychain
  • OPML
Boost Weather app artwork: the white Boost Wx wordmark over a receding road on a black background

Boost Weather: Air Density

  • iPhone
  • Apple Watch

A pre-drive air check for performance cars. Temperature, dew point, station pressure, and elevation from Apple Weather become eleven air values, from density altitude to the SAE J1349 dyno correction, and one Green, Yellow, or Red verdict graded against thresholds set per car, with the reason. The Apple Watch app reads the air on its own, and each complication picks a metric and tints it by its grade. On devices with Apple Intelligence, an on-device Foundation Models summary names the check that decided the color and never changes the verdict. The atmosphere math is a Foundation-only Swift package shared by phone, watch, and widgets, with car profiles synced through SwiftData and CloudKit.

  • Swift 6
  • SwiftUI
  • SwiftData
  • WeatherKit
  • WidgetKit
  • watchOS
  • CloudKit
  • Foundation Models
  • Xcode Cloud
Pulse app artwork: a gold heartbeat line on a dark background

Pulse: Widgets for GA4

  • iPhone
  • iPad
  • Mac
  • Apple Watch

Glanceable Google Analytics for people running more than one site. Live visitor counts land on the home screen, the lock screen, the Apple Watch, and the Mac menu bar, each stamped with an honest "as of" time so a stale number never reads as a live one. Built as a single multiplatform Swift 6 target under strict concurrency, with hand-rolled OAuth 2.0 PKCE, Keychain-stored tokens, and a SwiftData cache shared across targets through an App Group. Zero third-party dependencies.

  • Swift 6
  • SwiftUI
  • SwiftData
  • WidgetKit
  • watchOS
  • StoreKit 2
  • OAuth PKCE
  • GA4 Data API
  • Xcode Cloud
SiteGrade app artwork: a green patch-cable letter A on a dark background

SiteGrade: Security Check

  • iPhone
  • iPad
  • Mac

A security report card for any website. Enter or share a URL and SiteGrade grades what the site actually serves browsers, A to F: security headers, the TLS certificate chain and expiry, DNS and email-auth records, HTTPS redirect behavior, and mixed content, with every finding explained in plain English. All checks are passive and read-only. The scan engine sits directly on Network.framework and dnssd, with hand-written DNS wire parsing and DER certificate decoding, in one Swift 6 codebase under strict concurrency for iPhone, iPad, and Mac. Zero third-party dependencies.

  • Swift 6
  • SwiftUI
  • SwiftData
  • Network.framework
  • dnssd
  • WKWebView
  • StoreKit 2
  • Share Extension
  • Xcode Cloud

Open Source

Tools I built for my own projects and open-sourced.

Open Source

A11yHawk

The open-source, self-hostable accessibility scan engine behind AccessHawk. Loads a page in a real browser, runs Lighthouse audits, and optionally has an LLM of your choice analyze the full page against WCAG criteria. No accounts, no telemetry.

  • Free Lighthouse-only scans in seconds, no API key
  • BYOK AI analysis against every WCAG criterion
  • JSON, markdown, and self-contained HTML reports
  • Annotated screenshots with issues boxed on the page
  • CLI with CI gating, HTTP server mode, Docker image
  • TypeScript
  • Node.js
  • Playwright
  • Lighthouse
  • OpenRouter
  • Docker
Open Source

AI Agent Plugins

An open-source plugin marketplace I write and maintain. Each plugin packages a repeatable task as skills: code audits, Azure DevOps updates, git automation, and Swift release checks. All 13 run in Claude Code, and 8 also run in Codex and Cursor.

  • Security audits and pnpm supply-chain hardening
  • Performance audits for bottlenecks and N+1 queries
  • Accessibility audits against WCAG
  • Azure DevOps work items and time logging over MCP
  • Git automation and Swift release-readiness checks
  • Claude Code
  • Agent Skills
  • MCP
  • Azure DevOps
  • Playwright
Open Source

UmamiDash

Real-time analytics dashboard for self-hosted Umami instances. Built it to monitor website traffic across multiple sites without switching between Umami tabs.

  • Real-time visitor and pageview monitoring
  • Multi-site dashboard in a single view
  • Connects to any self-hosted Umami instance
  • Vue 3
  • shadcn-vue
  • Express
  • TypeScript
  • Umami API
Open Source

UmamiHA

Home Assistant integration for self-hosted Umami analytics. Built it to surface website traffic data directly in my HA dashboards without checking Umami separately.

  • Real-time active visitors sensor
  • Pageviews, visits, and bounce rate tracking
  • Multi-site support with per-website sensors
  • Installs through HACS
  • Configurable update intervals
  • Python
  • Home Assistant
  • HACS
  • Umami API

Technical Blog

What I'm working on and what I've figured out.

View All Articles
Thumbnail for Hosting a Vision Model for Medical Images Under HIPAA: Self-Host, AWS Bedrock, or Azure OpenAI?
AIHealthcareHIPAA+7 more

Hosting a Vision Model for Medical Images Under HIPAA: Self-Host, AWS Bedrock, or Azure OpenAI?

A working engineer's guide to running a text-plus-image AI model on protected health information. What PHI, covered entity, and BAA mean in plain English, the three realistic hosting paths (self-hosted open-weight models, AWS Bedrock, Azure OpenAI and Foundry), where the paperwork gets murky for image inputs specifically, and the checklist to run before the first byte of PHI moves.

17 min read
Thumbnail for Apple Rejected My App Eight Times. Here's the Playbook I Wish I Had.
App StoreAppleSwift+7 more

Apple Rejected My App Eight Times. Here's the Playbook I Wish I Had.

Three apps through App Review in one summer: SereneReader, Pulse, and SiteGrade. One of them collected eight findings in three rejection rounds. Here is what App Review flags, what the real cause usually is, and which rejections you answer with a reply instead of a build. Covers the sandbox-on-production trap, Sign in with Apple on macOS, closed version trains, Terms of Use metadata, and how to write the reply.

20 min read
Thumbnail for I Open-Sourced the Engine Behind AccessHawk. Meet A11yHawk.
A11yHawkAccessHawkAccessibility+6 more

I Open-Sourced the Engine Behind AccessHawk. Meet A11yHawk.

A11yHawk is the open-source, self-hostable accessibility scan engine that powers AccessHawk. Real browser capture, Lighthouse audits, and bring-your-own-key AI analysis against every WCAG criterion. Build your own accessibility tooling without the per-scan SaaS bill.

9 min read
Thumbnail for 84 Malicious TanStack Versions Hit npm. My Portfolio Pulled Zero.
npmpnpmTanStack Start+4 more

84 Malicious TanStack Versions Hit npm. My Portfolio Pulled Zero.

On May 11, 2026, the Mini Shai-Hulud worm published 84 malicious versions across 42 TanStack packages in a six-minute window. My portfolio runs on TanStack Start. None of the bad versions ever touched it. Here is why, and what every project running npm should be doing right now.

12 min read
Thumbnail for That Accessibility Widget Isn't Protecting You. It's a Lawsuit Waiting to Happen.
AccessibilityWCAGADA+4 more

That Accessibility Widget Isn't Protecting You. It's a Lawsuit Waiting to Happen.

Accessibility overlays like AudioEye and accessiBe promise WCAG compliance with a single line of JavaScript. The FTC, the courts, and the disability community all disagree. I dig into why overlays fail, what legal exposure they actually create, and what it takes to build accessibility into your source code.

13 min read
Thumbnail for Railway Is My Go-To Infrastructure. Here's Why I Recommend It to Enterprise Teams
RailwayInfrastructureDevOps+5 more

Railway Is My Go-To Infrastructure. Here's Why I Recommend It to Enterprise Teams

I run several production projects on Railway, from SaaS platforms with background workers to simple marketing sites. After years on AWS and Azure, Railway cut my go-to-live time from days to minutes. Config-as-code, built-in databases, non-serverless deployments by default, and a platform that ships meaningful features weekly.

14 min read