March 1, 2026•3 min read
When I joined DFINITY, I started working on the original NNS dapp.
It handles a lot: ICP accounts, staking, neurons, proposals, voting, rewards, and several expert workflows built over many years.
That scope is useful. It also makes the product difficult to simplify.
Changing one flow can affect people who already understand the product and depend on its current behaviour. We could improve individual screens, but a larger redesign would always carry the risk of disrupting established users.
I proposed a separate governance app instead.
The idea was not to replace the existing product at once. It was to create a simpler path into the parts most people need: staking, voting, delegation, accounts, and rewards.
The result is now live at nns.icp.net.
We started with something disposable
Before we committed to production work, I built a quick AI-assisted prototype in an internal repository.
The code was not meant to survive. Its job was to make the idea real enough for people to use and discuss.
That changed the conversation. Stakeholders could click through the flows, react to actual decisions, and see where the simpler model worked or failed.
We kept the prototype around while exploring later capabilities. For production, we started again.
Production needed a different setup
The production application uses React and TypeScript on the frontend, with Rust canisters on the Internet Computer.
I wrote the initial architecture documentation and some reference code. I also set up CI, tests, type checks, human review, and a local QA environment.
Agents helped us move faster, but they worked inside those constraints. They could run the application, inspect their work, and fix problems before asking for review.
That distinction mattered to me. The prototype optimized for learning. Production needed code that the team could understand, test, and operate.
My role changed with the team
I proposed the product and became its main point of contact. I led the frontend direction and worked closely with the other frontend and backend engineers.
This was team work. Other engineers shaped the implementation, contributed features, and reviewed the canister work.
As the team became smaller, my scope grew. I took on more backend work, security, dependencies, documentation, CI, releases, production fixes, and stakeholder discussions.
I also continued maintaining the original Svelte application.
Releasing without waiting for feature parity
We released the first production version at the end of January 2026. We used February for dogfooding, fixes, and more features before announcing it publicly.
We did not wait for full feature parity with the original app. That would have defeated the point.
The first release needed to be useful on its own. Later releases could add value without inheriting every decision from the legacy product.
Today, both governance applications receive about 50,000 monthly visitors across their separate Plausible dashboards. This is combined traffic, not a count of distinct people across both products.
What I would do again
I would still separate the prototype from production.
Trying to turn fast prototype code into production code often looks cheaper than starting again. In my experience, that cost returns later through unclear boundaries, fragile tests, and decisions nobody remembers making.
The prototype helped us answer whether the product should exist.
The production application had to answer a different question: can we keep building and operating this safely?
Those were different jobs, so they needed different code.