My current work is shaped by both large-scale product engineering and years spent helping other people learn how to build.
Block, formerly Square · 2018-2023
Five years building at scale.
I spent five years at Block, formerly Square, becoming a Staff Software Engineer within two years. That experience sharpened my bias for useful developer experience, resilient systems, and changes a team can confidently own after launch.
Among the work I can point to: backend and database improvements that brought page-load time from over five seconds to under one second.
LaunchCode · 2016-2018
I used to teach the craft.
Before that, I was an Engineering Tutor and Mentor at LaunchCode, teaching and supporting emerging engineers in Python, Java, and JavaScript.
Teaching made one thing permanent: code is only useful when its reasoning can be shared. That still informs how I write interfaces, explain tradeoffs, and review a system with a team.
What “Engineering” is to me.
It is not a title for writing more code, faster. It is the practice of making sound calls when product pressure, technical risk, and the future of a system all arrive at once.
Speed is not quality.
Quickly written code is not automatically good, clean, or maintainable. Delivery includes the clarity to change it safely after the first release.
Know when rough is right.
Quick and dirty can be the right call when its scope, cost, and expiration are explicit. It becomes a problem when a temporary shortcut quietly becomes the system.
Challenge the generated answer.
AI can miss the important constraint or overengineer the visible one. I use it to move faster, then apply context, product judgment, and review to decide what belongs.
Types and tests stay essential.
AI does not make types or tests redundant. It makes them more valuable: they are the shared evidence that a generated change still behaves as the system intends.
Project records
Three different products, each built around the same question: what helps people do the real work in front of them?
01 · Founder and product engineer
TheBoardGuide
A multilingual product connecting physical board-game shelves to searchable inventory, customer discovery, lending and floor workflows, and public shop pages.
It is a systems problem disguised as a friendly local product: the data needs to serve shop owners, staff, and players without forcing one person’s workflow onto everyone else.
Shared domain modelThe shared domain model is the seam between discovery, lending, staff workflows, and public shop pages.
I set product direction and technical architecture across shared domain models, public and private surfaces, localization, data boundaries, and safe releases. I also coordinate specialized AI coding agents through clear interfaces and acceptance checks.
React and TypeScript across the product surface, with automated checks supporting full-stack changes.
Careful separation between public discovery, operational workflows, and the data that connects them.
Deliberate localization and release boundaries so an early product can grow without becoming opaque.
A Japanese language-learning application built around short, repeatable games for Hiragana and Katakana practice.
I wanted the learning loop to work when a learner had a few minutes, a poor connection, or just enough attention to make the next bit of progress.
Short study sessionThe experience starts with a small, repeatable exercise that fits the time and attention a learner has right now.
Beyond the interface, the project was an opportunity to make the application behave like a dependable study tool: installable, usable offline, and able to extend from kana practice into Kanji study.
Built custom Vite plugins to support the PWA implementation and offline experience.
Designed focused game modes for Hiragana and Katakana practice instead of a generic flashcard surface.
Integrated a third-party Kanji API so the application could meet learners beyond their first exercises.
A browser interface for people using local AI models, designed around privacy, offline use, and the messy reality of switching among tools and models.
The project lets me explore where AI interfaces reduce friction and where clarity, user control, and technical limits need to remain visible.
Local modelsThe interface begins with local-model workflows, where privacy, offline use, and model choice remain visible to the person using it.
LLM-X supports streaming input, multi-image input and output, multiple chats, theme settings, code highlighting, and search in a React and TypeScript application with MobX, LangChain, PWA, and Chrome-extension work.
Built for local-model workflows rather than assuming a hosted service is the only useful path.
Kept complex application state approachable across conversations, model connections, media, and preferences.
Used the project to test practical AI interaction patterns with real constraints instead of treating a model response as a finished feature.
I use Claude and Codex to explore options, accelerate implementation, and reduce the cost of a first draft. That is useful work. The responsibility for the architecture, interfaces, tests, review, and decision to ship stays with the engineer.
The misuse begins when generated output is treated as understanding. It can miss a constraint, make a locally tidy change that breaks a system boundary, or give a team a convincing answer without a way to maintain it. Faster generation should buy more time for clarity, validation, and human impact, not excuse less of each.
Frontend architecture is how product change stays possible.
The frontend is where product decisions, data contracts, accessibility, performance, and the day-to-day reality of a user meet. Clear boundaries and reusable foundations help a team make a change once, understand where it belongs, and release it with confidence.
When that work is ignored, the cost does not disappear. It returns as duplicated behavior, fragile state, inconsistent experiences, regressions, and a team that becomes afraid to touch important parts of the product. Architecture is not ceremony. It is the shared structure that lets a product keep moving.