Work

Apr 2026 – now

live

CourseTrees (opens in a new tab)

A course catalog is a few thousand paragraphs with the prerequisites buried in the prose, which makes it a graph pretending to be a list. CourseTrees parses the prose back into edges and lets you walk the result: click a course and see what it needs and what it opens up, next to grade distributions, ratings, and degree requirements. Live across 150 universities. The layout is a force simulation written by hand and run in a web worker, because no off-the-shelf layout stayed readable at catalog scale. Co-founded with Rohan Vittal. Built with Next.js, TypeScript, Cytoscape, Python, PostgreSQL and Supabase.

The CourseTrees map of Brown's courses: colour-coded course nodes joined by prerequisite arrows, clustered by department.

Aug 2026

open source

The Sopranos CLI (opens in a new tab)

Prints a quote from The Sopranos next to an ASCII portrait of whoever said it. POSIX sh and awk, no dependencies, and the repository doubles as its own Homebrew tap. The portraits are hex-digit pixel grids rendered at runtime as grayscale Unicode half-blocks, two pixels per terminal cell, downsampled to whatever size your terminal happens to be. Built with sh and awk.

A terminal running sopranos: a grayscale half-block portrait of Tony Soprano above one of his quotes.

Jul–Aug 2026

live

BrownSync (opens in a new tab)

A live map of what is happening at Brown right now: events, club meetings, classes in session, athletics. It pulls from LiveWhale, an athletics calendar feed, campus news, and OpenStreetMap onto a 2.5D MapLibre map locked to College Hill. The TypeScript app and the Python ingestion pipeline share no code at all — they stay compatible by implementing one written data contract twice, as Zod schemas on one side and Pydantic models on the other. Built with TypeScript, MapLibre, Python, Zod and Pydantic.

BrownSync's 3D map of College Hill, with buildings that have classes in session lit up and a feed of upcoming events beside it.

Jul 2026

open source

brown3d (opens in a new tab)

Walk around Brown’s campus and downtown Providence in a browser. The 281 building footprints come from Brown’s public ArcGIS layers, extruded to heights read off USGS one-metre lidar and draped over terrain from the same survey; a Python pipeline turns 80 raw layers plus OpenStreetMap into the runtime assets. 272 buildings get a real lidar height, three are estimated from floor area, six fall back to a default, and the pipeline writes down which got which rather than hiding the difference. Built with TypeScript, three.js, Vite and Python.

An aerial view in brown3d over Brown's Main Green, with extruded brick buildings running to the horizon.

Jul 2026

unreleased

Campus Clash

Students at the same school compete on the same daily minigames — sudoku, memory, archery, hoops — on a leaderboard gated by university email. The two arcade games are SpriteKit. The Firestore rules and Cloud Functions for scoring and weekly tournaments are written but not yet wired up, so for now it all runs on local state. Built with Swift, SwiftUI, SpriteKit and Firebase.

Spring 2026

course project

Distributed key-value store

A sharded key-value store in C++: a shard controller that assigns key ranges to servers, and a client that routes each operation to whichever server currently owns that key. There is one reader-writer lock per hash bucket, and multi-key operations sort and deduplicate their bucket indices before taking any of them, so two concurrent MultiPuts cannot deadlock against each other. Built with C++.

Terminal panes for the shard controller, a client and three servers, showing key ranges being moved between servers.

Fall 2025

course project

BetaGo

A Go agent for the 9×9 board, written to compare greedy, minimax, alpha-beta, iterative deepening, and Monte Carlo tree search under a fixed per-move time budget. The winner was not the interesting-sounding one: alpha-beta at depth 3, with a small learned value network standing in for the stone-count heuristic, took 293 of 300 games from the greedy baseline and 99 of 100 from depth-2 alpha-beta, while MCTS never beat alpha-beta at any depth I tried. Built with Python and PyTorch.