Code is not public
CoFounder is an AI platform for startups and small businesses. It brings together all of your businesses data to save you time, money, and help you run your business.
The web application is written in TypeScript/React using the Next.js framework and Vercel for hosting. We chose that stack specifically because we were optimizing for speed to market and ease of iteration.
I spent most of my time on the AI side of the product, which is written in Python using the FastAPI framework and LangChain to interface with various foundational models and internal data sources. I redesigned our existing RAG pipeline to be modular and support a second product and re-wrote our system for adding user data to the LLM's context window.
The product was also intended as an exploration of the AI space, so I also conducted a few experiments around query augmentation, agents, document hierarchies, and more.
Code is not public
MainStreet is the leading tax credit platform, offering credits like R&D, retirement, healthcare, and more. It has delivered over $200 million of savings to customers by qualifying customers for credits and automating the generation of the form required to claim the credit.
The core application is a group of Node.js services and React front ends deployed to Google Kubernetes Engine. There is also a series of AI-powered features built in Python using the FastAPI framework and LangChain to interface with various foundational models and internal data sources.
I worked on every facet of this product across the entire stack, from the front end to the back end services, and even kubernetes cluster managed by Terraform.
The first major project I undertook was a rewrite of the ETL pipeline that imported customer accounting and payroll data. The pipeline was plagued with errors, crashes, and unexpected behavior — on top of generally poor performance. I led the analysis, wrote the project proposal and design doc, then implemented a new ETL pipeline and queuing strategy that led to a 500% increase in processing efficiency, the elimination of crashes, and a massive reduction in errors/incorrect data.
After we transitioned to the new pipeline, I then helped to design and implement algorithms to improve data reliability and reduce duplicate data.
I am particularly proud of the part I played in redesigning our core data model for tax credits and tax forms. Over the course of many months, I built support for the data model work and successfully resourced a team to design and implement it. This work allowed the company to expand its product offering beyond a single tax credit (R&D) to retirement, healthcare, and more.
While collaborating with the team doing the data model work, I separately led the work to implement the newly-supported tax credits in our core product. This required two entirely new user experiences: a dashboard to guide users through the credit claiming process and a survey to collect the necessary information, the latter of which required a new algorithm to collect, filter, clean, and insert user data in order to reduce manual data entry. This work made it significantly easier for customers to claim their credits by streamlining the form generation process and resulted in 10% more revenue per customer.
I also led the effort to integrate AI into the product, which included productionalizing a proof-of-concept chatbot, developing custom evals, building an internal benchmarking tool, significantly improving our RAG pipeline performance, and building an efficient system for including user data in LLM context windows. We were afforded the opportunity to explore the AI space, as well, so we also conducted a few experiments around query augmentation, agents, document hierarchies, and more.
Code is not public
Upright (neé FundThatFlip) is a real estate financing and investment platform. It provides loans to established home builders and offers institutional and accredited investors the opportunity to invest in those loans.
The main product was built with Ruby on Rails and React when I worked on it, but has changed significantly over the intervening period.
One of my biggest accomplishments while working on Upright was helping to design and implement a payment system built directly on top of banking APIs that moved $10+ million per day at peak. The business has extremely unique needs when it comes to money movement — it loans millions of dollars to builders through a complicated series of legal entities, accepts millions of dollars of investment from institutional and accredited investors, and then pays interest and principal to those investors on their investments.
To support these needs, the payment system needed to be extremely resilient and interface directly with banking APIs to programmatically open up new accounts, fund those accounts, and perform balance sweeps to ensure the accounts remained in good standing. The system would determine which accounts were to be used to pay how much to which investor or loan recipient, move that money programmatically, ensure the funds settled correctly, and perform any necessary dunning.
Underlying every payment was a calculation done by a calculation engine that I helped design, implement, and thoroughly test. Previously, a given calculation's logic was written close to where the math was needed — so if it was needed on the front end, the calculation lived there; if it was need for both underwriting and payments, then it was duplicated in both places. This was an inflexible and unreliable system that was impossible to maintain and very vulnerable to errors, so we decided to design a set of composable calculation objects in the back end that could also be accessed by the front end via an API.
That design decision significantly improved the calculations we did at every level of the application. It allowed us to refactor our loan underwriting tool to use the new calculation engine, which significantly increasing the tool's reliability and improving the business's ability to accurately assess a loan applicant.
Due the nature of running a financial application, we also spent a large amount time identifying and addressing fraud. I designed and built our initial fraud detection system, along with the custom algorithm we used to judge each individual user and individual transaction to prevent things like spam account sign ups and to significantly reduce the likelihood any money was lost to fraud.
View the code on Github
I came of age on the internet when surfing the web still felt like an adventure, when it was so full of new that you never knew where you'd end up. Back then, it wasn't uncommon for someone to set up a web server and allow anyone on the internet to peruse parts of it as a remote file system — just from within a web browser. Those sections of a website would rarely have an index.html file so the server would render the current directory as web pages using a "default directory view," which was usually just a white background and a table containing blue links.
A part of me misses the aesthetics of that era of the internet, before things like Bootstrap or Tailwind popularized certain styles and hyper-optimized landing pages all started converging on the same, generic look. The look of default directory views is the exact opposite kind of convergence — the internet and websites were so new that those white pages and blue links had a feeling closer to being on the frontier, exploring the depths of some stranger's web server. (Google initially retained some of that feeling, and in fact used the same aesthetic, when it rose to prominence...but it lost that sense long ago.)
When I bought my personal domain, I wanted to both avoid building a generic portfolio and have a little fun with the task in front of me. So I did what any sane person would do: I leaned hard into a joke-y, nostalgic aesthetic that few people remember. Is it a good idea for your personal site to be, quite literally, a joke? Specifically a joke that you have to explain? Is it even a good joke if I have to explain it?
Probably not, but I enjoyed building it anyway.
Programming is, at its core, a creative act. That often gets lost in the day-to-day work of software engineering, but it really comes to the fore when you are working on personal projects.
One of my favorite adages in that vein comes from Mark Rosewater, the Head Designer of Magic: The Gathering. For well over a decade, he has lived by the philosophy that "restrictions breed creativity."
"This lesson is tied into a myth about creativity," Rosewater writes. "Many people believe that the more options available, the more creative a person can be."
"This is a myth," he continues, "because it contradicts what we know about how the brain works." If you're faced with a problem and you've solved that specific problem before, he says, you will likely solve it again in the same way — the opposite of creativity.
Instead, Rosewater argues that "[i]f you want your brain to get to new places, start from somewhere you've never started before." Using a restriction, arbitrary or not, to force your brain to start from a new place off of the beaten path will help kickstart the creative process.
If I'm being honest, this concept is only a small part of why I built my personal site as a neo-default directory view and mostly a post hoc justification for the time I spent building something that isn't obviously "good." But, alongside my decision to use default directory aesthetics, I decided to try and mirror default directory functionality as well. And that is definitely a restriction.
So I limited myself to a table-like layout with narrow rows and columns. Nothing fancy — no hero images, slideshows, image animations, etc — and a mono font styled with a very basic color palette.
I learned to build my first websites back when those web server directories that did have an index.html were forced to use tables as the main way to achieve a non-standard layout. It's an absurd thought in today's age of CSS grid and flexbox, which have fully supplanted tables — even when building actual tables for a web page — but tables used to rule the web. But I never really felt like the transition to floats and clearfixes for layouts was that much of an improvement, at least until Bootstrap 3 made them predictable enough to commit to.
The visual layout of the default directory view is essentially a table, so falling back to the familiar old ways of table-as-page-layout-device was all to easy. I would obviously come to regret using a table...but we'll get to that later.
The basic structure of the site was simple enough to translate to the default directory view as that view was literally used to visualize the file system of a web server. The top level pages would get their own links on the landing page, but figuring out the other parts of the site was where the fun was to be had: made-up server signatures in the footer, expanding table rows for details, etc.
I think it turned out pretty well — except for the use of tables. As I return to the site more than 10 years after I wrote the first iteration, it is clear that the unpredictable nature of the table element no longer cuts it. Plus, AI tools have come a long way and products like v0, Claude 3.5 Sonnet, and Cursor make work on my side projects a lot more effective. So I've re-written the site with the help of those three tools and am quite pleased where it ended up.
I wanted to play around with Next.js again, so I converted the site from HTML and vanilla JavaScript to a static Next.js app served via Github pages. v0 helped me translate the classic default directory view style into a more modern React and Tailwind setup, while Claude and Cursor helped me rewrite the the site to remove the use of tables in favor of CSS grid.
The site definitely isn't everyone's taste but I sure have loved working on it over the years. I should probably build a more generically good-looking site for those hiring managers (or any other poor souls that stumble upon this site) that either don't get the aesthetic joke or just don't enjoy it. But not today!
MTGCast launched in 2014 in order to provide a free, shared podcast hosting platform for the Magic: The Gathering community. In 2018, the site experienced a catastrophic failure and lost the majority of its data. The operators at the time weren't up to trying to recover the site, so I stepped in and began the painstaking recovery and reconstruction of the service.
Unfortunately, the database was irretrievable. I was able recover a large portion of the audio files that MTGCast users had uploaded, but that was the only data with which I could restore the site's historical data. The result was very incomplete but I managed to re-host all of the recovered audio files under properly-organized RSS feeds.
MTGCast had already been down for a few weeks by the time I got involved. Given the level of data loss, I decided that rebuilding the basic functionality of MTGCast from scratch would be faster than recreating the previous WordPress-based version that had already begun to come apart at the seams. Speed was still important, though, so I chose Rails to quickly scaffold out the podcast creation, episode upload, and RSS feed features.
After restoring service, the immediate flood of traffic forced me to refine my caching techniques ahead of schedule, particularly for the RSS feeds I was programmatically generating for each podcast. I then proceeded to flesh out the podcast management side of things by adding a second database to store records individual downloads, which were then processed asynchronously into aggregated analytics data. I also added a file compression service to reduce my AWS data costs and expanded the content types to include text posts, which required upgrading the text editor to use tiptap.
The service continued to evolve over the next few years but never really recovered from the initial failure. I stopped actively developing the site in 2022.
Thousand Leagues was a first-of-its-kind esports fantasy site focusing on Magic: The Gathering events. It was built with Ruby on Rails and React.
I have played fantasy football with friends and family for over a decade. I love the game and have noticed that it has a very distinct ability to increase a fan's engagement with an individual football game by almost always giving them a rooting interest in every game.
(The NFL certainly noticed, too, and put the full force of its marketing behind pushing fantasy football...at least until sports gambling was legalized and everything became a gambling commercial.)
I wanted to test the hypothesis that a fantasy game would have a similar impact on esports, my favorite of which is Magic: The Gathering. Plus, I wanted to learn how to build a real-time application, so I chose this project as a way of accomplishing both.
Thousand Leagues supported multiple ways for people to play fantasy Magic. Initially, the primary game mode was focused on private leagues, where you could get together with your friends for a specific Magic tournament and snake draft your favorite players. That format was the inspiration for the project and was powered by web sockets and React to create a real-time drafting experience.
Later, I introduced the pick 'em format for use in public leagues that anyone could join. This was by far the most popular way to play on Thousand Leagues — I ran nearly 100 tournaments and gave away tons of non-monetary prizes.
On Thousand Leagues, a league could choose between two different kinds of "players" to draft: actual professional Magic players or specific Magic cards. The player data was sourced from a combination of event registration and results from the tournament website, as well as historical data and rankings from The MTG ELO Project. The card data, on the other hand, was sourced from a combination of historical tournament metagame reports from MTG Top 8 and the specific decks registered for that particular tournament (if publicized by the tournament organizer). I built a flexible ETL pipeline to pull in that player and card data, process it, and then load it into the database so it could be presented to users during the draft.
The results of the actual games of Magic were then automatically updated at the end of each round so that fantasy players could have as close to a real-time experience as a Magic tournament would allow.
I also had the opportunity to partner with a third party to run a custom Magic-themed March Madness event on the platform that drew thousands of players. Instead of drafting, players would create a bracket out of 32 characters from the most recent Magic set (called War of the Spark, so the event was called "Spark Madness"). This required building a new UI with d3.js to display brackets and allow users to predict the winners of each round. My partner then ran polls to determine the round winners and we gave prizes to the players with the most accurate brackets.
Unfortunately, Magic events went on a long hiatus during the COVID-19 pandemic and never returned to their pre-pandemic frequency or level of fan interest. As a result, I stopped developing the site in 2020.
View the code on Github
Team Magic League (neé Team Draft League) was born in 2013 when a group of Brooklyn-based Magic: The Gathering players wanted a way to organize and track team drafts. We formed a league — and what does every league need? Schedules, results pages, and leaderboards. So I stepped in and built my first actually-used-by-real-people side project.
Looking back on the code base is an exercise in cringing over and over. It's a basic CRUD Rails app with a lot of poorly thought out data modeling, incorrect use (or pure ignorance of) Rails conventions, or really any best practices, and just a lot of beginners mistakes. But I'm incredibly proud that a group of 20-30 people used this site for years to keep our little league going.
The core functionality of the app was the creation of a league, seasons, teams, and players. Those teams (usually made up of three people) would schedule matches against each other, where players would play everyone on the other team in 1v1 matches of Magic. The results would be reported on the website, aggregated to create seasonal leaderboards, personal statistics, etc.
I stopped actively developing the site in 2015 as the original incarnation of TDL ceased operations.
View the code on Github
Hipsters of the Coast was gaming content and news site built on WordPress that reached over 2 million users annually at peak and 60% growth year-over-year from 2017-2023.
It employed a remote team of 10 and generated $100k+ in revenue, mostly through advertising.
The site was started by a group of Brooklyn-based friends in 2012 in write about our favorite game, Magic: The Gathering. I joined in 2013 in order to help my friends transition away from WordPress.com to a self-hosted version of WordPress.
I took on all of the web-related duties at that point. At a basic level I managed our servers and WordPress implementation (eventually transitioning to a hosted solution), but I also redesigned and re-branded the site (including the graphic design) and built new features (like an advanced card hover plugin).
In a non-technical capacity, I helped run the content side of the business between 2017-2023, which involved managing our remote team of writers through the entire editorial process.
Hipsters of the Coast ceased publication at the end of 2023.