A collection of experiences, learnings, and "aha!" moments from my software engineering life. I share my discoveries, struggles, and insights that might help fellow developers.
2026 is almost over, and this is only my third post on this site. It's been a hell of a year at work and on side projects. Today I wanted to share a bit about what I've been building: PropertyOS, a property-accounting platform for rental operators. I've never shipped anything close to this scope before.
With AI helping on almost every layer of the stack, I ended up wearing a lot of hats on this project: product, frontend, backend, DevOps, QA, design, and plenty more I didn't have job titles for. I chose to build the whole thing in one monorepo. The codebase is now over 700k lines — about 13× my previous largest project. That number still feels unreal when I look at it.
I think I found (again) why I love software engineering: learning never ends. At the start of every project I tell myself I've seen most of what's out there — and then I land in something new and pick up dozens of tools I'd never touched. PropertyOS was that on steroids.
A non-exhaustive list of what showed up along the way:
The fun part is how much there still is to learn. The scary part is the same — we're not even done yet.
I'll write more about PropertyOS later: architecture, local dev, integrations, and whatever else is worth unpacking. For now, thanks for reading — take care.
I haven't posted here in a while. This site is mostly a diary for myself, but today I tried something that actually fixed a daily annoyance, so I'm writing it down before I forget.
I've been shipping full-stack work more often. AI shows up everywhere in the stack now, but I'm still the only developer on these repos. One monorepo has been the sane choice: shared types, one place for scripts, less copy-paste config across a bunch of tiny repos.
What kept getting in the way was local dev. Seven services, seven terminal tabs. That was fine until the terminal app quit or I closed the wrong window. Then it was seven start commands again, hoping I didn't skip one.
concurrently got me to a single command, which helped. Every log still lands in one stream though. Prefixes are okay until the API, a couple of frontends, and workers all chatter at once. I was spending more time figuring out who logged something than fixing the bug.
I set up mprocs today for the first time.
It's a TUI: one pane per process, shortcuts to jump between the server, frontends, workers, whatever you wire in. Same monorepo scripts I already had. I just stopped juggling windows. Debugging locally felt quiet for once instead of one long interleaved scroll.
Small aside. I started in product, project management, and design. These days I'm writing frontend and backend, touching infra, keeping tests green, all in one loop. I like that. Things move faster when I'm not waiting on handoffs, and less slips through the cracks.
I'll probably ramble about that more in a future post. For now I mostly wanted a note on the site that mprocs exists, so future me doesn't go back to seven tabs.
This was a year-long journey that transformed how we build software. We migrated over 50 React.js applications into a single, unified system that manages them all—and it completely changed the trajectory of our product.
We were dealing with a very large, fragile codebase—over a million lines of code—that was slowing down everything: development, testing, deployments, and starting to negatively impact user experience. The system had grown organically over years, and technical debt was compounding daily.
Every change felt risky. Every deployment was nerve-wracking. The codebase had become a liability instead of an asset.
I proposed a foundational architectural rewrite that would dramatically simplify the entire system. It was a risky move—the product was driving roughly $50M worth of traffic, and initially, most stakeholders were against it due to the potential risk.
But I believed it was necessary. The status quo wasn't sustainable, and the longer we waited, the harder it would become.
I took full ownership of the initiative. I put together a clear technical plan, de-risked the rollout with incremental migration strategies, and personally stood behind the outcome. This wasn't just about writing code—it was about convincing stakeholders, managing risk, and executing carefully.
We executed it incrementally and safely, migrating applications one by one, ensuring stability at every step. No big-bang releases. No downtime. Just careful, methodical progress.
The results were significant:
That's right—we went from 1,000,000+ lines to ~30,000 lines. A 97% reduction in codebase size while maintaining all functionality.
What I'm most proud of isn't just the technical win, but the company-wide impact:
This migration touched every part of the organization, and the improvements cascaded through every team.