Selected work

THE PROJECTS

apps, demos & experiments

A selection of things I have built — production work, side projects, and the occasional experiment. Each card includes the context, stack, and links to the live version or source code.

APP 01

The Orange Mate

Social platform for solo travelers

A full-stack social app where solo travelers find companions and split travel costs. Built with Next.js 15 and Supabase, it ships authentication, a personalized dashboard, real-time 1-on-1 chat, a friends system, trip plans with discovery filters, and reviews — covered by Playwright E2E tests.

Next.js 15TypeScriptSupabaseTailwind CSSPlaywright
APP 02

Dungeon Hub

D&D companion for a West Marches campaign

A monorepo companion for an asynchronous, multi-DM D&D 5e world: character management, a browsable rules compendium, a campaign map, and a world-knowledge layer. A Fastify API, a Next.js web app, and a Discord bot share a pure domain package with Zod schemas as the single source of rule truth.

TypeScriptFastifyNext.jsDrizzle ORMSupabaseDiscord.js
TOOL 03

peel

Ephemeral git worktrees with managed dev servers

A published CLI that spins up any branch in an isolated git worktree with its own node_modules, a copied .env, and a free port — then tears it all down on exit. Distributed on npm as @tanisjam/peel.

TypeScriptNode.jsCLInpm
TOOL 04

Orange Grove

A portable Spec-Driven Development harness

A tool-agnostic SDD harness with a hard rule: no implementation before approved specs. Eight phases and eight specialist agents, pure-markdown specs, and dependency-free validators that enforce requirement-to-task-to-evidence traceability across Claude Code, Cursor, opencode, and Codex.

Node.jsMarkdownSpec-Driven DevCLI
APP 05

Just a Drop

Ephemeral audio drops that vanish after one listen

Record a voice note in the browser, get a short shareable link, and send it — the recipient plays it once, then it is gone. Chunked uploads stream to a self-hosted MinIO store, Redis enforces the one-listen TTL, and a daily Vercel cron clears expired drops — the whole backend runs on my homelab, reached through a Cloudflare Tunnel.

Next.jsTypeScriptMinIORedisCloudflare TunnelVercel
APP 06

Hecho Hex

Geospatial message board on a hexagonal map

Drop anonymous messages pinned to your location on a Mapbox map. Notes aggregate into Uber H3 hex cells, rendered as a word-cloud layer and floating draggable bubbles, with real-time updates via Supabase and a 48-hour expiry.

Next.jsTypeScriptMapbox GLH3SupabaseFramer Motion
STACK
BUILT WITH
ViteNextJSReactJSTailwind CSSTypeScriptReduxSassCSSHTMLJavaScriptStrapiSQLiteMongoDBBootstrapStyled-componentsNodeDockerJestGitHubJira