Frameworks and sketches

Week 2: Jan 4 - Jan 11, 2026

I cannot deny my ambition for these posts to be interesting.
Call it a writer’s conceit, but the desire to write well still possesses me.

To achieve that here, one thing is apparent: the content itself must be interesting.
Our week’s work must be interesting for these posts to have any merit at all.

That’s a very difficult thing.
I can’t imagine what the weekly diaries of most corporate tech workers would look like.

Perhaps “procrastinated in standup,” “participated in politics,” and “debated why I’m at this company” would be the most honest answers. Even excusing my cynicism, if answered properly by most, a week’s worth of work is typically not enough to constitute an artifact. It is just "some work," some tasks in this month-long project in this year-long roadmap.

But even knowing that, I think it is the right challenge for us to aspire to.
A week may seem short, and perhaps it is when caught up in the humdrum of routine, but in truth, it is an incredible amount of time.

Much of what we think about as “work” is dominated by the urgent: a mess of meetings, random Slack threads, and one-off tasks of questionable value. It is often rare, if at all, that people do work that actually counts. And it goes without saying, but the primary advantage of a startup is that there are no distractions.

So without further ado, here’s what we did this week.

 

We spent a lot of time researching.
I spent quite some time digging into the rabbit hole that is named Next.js and contemplating its seemingly contradictory design decisions, and Mikkel spent most of his week agonizing over Rust design patterns and debating domain-driven design intensely with Claude.

That must sound atypical for startups, and I must admit, I felt an impulse of impatience to load up Claude Code with credits and re-implement the same React / FastAPI stack we’ve done a dozen times before, but the reason we chose to do things differently is because we chose to emphasize quality.

The rationale for design decisions, especially at larger tech companies, is often about mitigating risk. Rather than choose that new, buggy framework that is potentially faster in half-a-dozen scenarios, you choose to opt for the well-known, well-baked framework that generally “just works.” That is to say, it is practicality that dominates discourse: doing the simplest thing possible as cheaply as possible.

Our goal is different.
Our aim is to build the best product possible — no matter the cost.

So when considering the choice of framework, we looked towards a single metric to optimize for: speed. What framework, what tool would enable us to push the upper bound? Push the theoretical limit on latency, even at the cost of engineering complexity and reusability.

 

Our answers were Next.js and Rust.

The choice of the former was more apparent.
Next.js itself is quite a complicated framework (some may even call it over-engineered) and was something I was aware of for quite a while, but never saw concrete reasons to move to as opposed to the single-page React stack I was familiar with. It seemed like it was adding too much bloat, introducing abstraction and convention where unnecessary, and re-inventing the wheel for the sheer sake of it.

But what brought me to it this time was this idea of static site generation.
The thought is: open-source repositories are just public sites and public sites are very different from private sites.

With private sites, as lightweight as you may make it, you cannot remove the need for some authorization function to run and validate on each request. Public sites are different: anyone requesting an asset or a page is granted access.

So we posit the question: why isn’t GitHub just a static site?
Why isn’t a repo just a blog — a collection of pages cached in the CDN.

There’s practical answers as to why not (and we’re well aware of those too), but by and large, I do think that most files could be cached. If we think about popular public repositories, though they may receive a steady volume of commits, it isn’t as if all those commits are changing all files. In fact, I’d bet that most files are unchanged and that only a fraction of files receive the majority of the attention.

How GitHub works right now is that it’s a single React SPA that loads and renders files upon click. With each interaction you take on the site, a loading blue bar lights up the top of your screen, and after making its appearance known for a couple hundred milliseconds (or longer), you’re taken to where you want to be.

It’s a very practical solution and for most, provides a user experience that is sufficient. But we seek to challenge that.

What if each click was instant, what if it felt like an IDE?
What if not only clicks, but even initial page loads were instant?
What if we could make things like on-type incremental fuzzy finding work?
What if we could make on-type incremental grep work?

These are the sorts of questions we ask ourselves.

So in short, we sought to make page loads as fast as possible while also minimizing bundle size, so we looked towards Next.js. We understood that it was designed for this use-case in mind, and not only that, offered quite a lot of tools to optimize things even further.

Next.js strikes me as an attempt to push the upper bound, an attempt to create the ideal user experience at the expense of engineering complexity (e.g., SSR / streaming / cache components), and while I do think their abstractions are heavy-handed, I admire the spirit.

 

The choice of backend was less obvious.
Most Git servers function by wrapping libgit2, a C library that spins up a separate process to execute git actions as specified. And given that most of our server’s processing would be dedicated to network & file I/O, we thought it unlikely that the choice of framework would make a tangible impact to latency.

There are some theoretical benefits to Rust, such as it would be a better option if we were to move to doing git operations in-process or if we were to try and fork ripgrep to do incremental live search, but they are relatively minute.

Fundamentally, it came down to preference.
And by that regard, both Mikkel and I were far more experienced with Python and FastAPI than we were with Rust and Axum. As Mikkel said, his design patterns in Python “are perfect.” They have been highly debated and are now finalized, to the point where he could argue as to why each line of code he wrote was the “right one” and explain the reasoning for even the most imperceptable of details.

But, as of now, we’re choosing to go with Rust.

One reason why is simply a spirit of engineering curiosity.
As odd as it is to say at my age, I do think Mikkel and I have been in a mode of engineering exploitation for far too long: doing the same things we know work and even teaching it to others too. Rust is something new, it is an opinionated language that is intentionally difficult to use. Using it forces us to learn and that spirit of learning is something we think will pay dividends in the long-term.

And while we won’t argue as to the theoretical benefits here, we also do predict that for the kinds of things we’re apt to try, we may find ourselves in situations where we’re glad to have picked a tool that enables us.

 

We also began sketching out the design.

As foreword, I’ll say that I’m not professionally trained in the field of design.
While I would say I have some aesthetic sensibilities (care far too much about interior decor and the clothes I wear), I know it a fool’s errand to think of a preference in optics as equivalent to a pedigree in the arts. But regardless of what I know, I’ve been challenging myself to approach design with the same rigor that we do engineering.

How I’ve been going about it is thinking about the intention behind each decision made.

It irks me to see products that are clearly a reflection of its creators' sensibilities. If this button is here simply because you want it to be, if this layout has this margin simply because it feels “comfortable” to have it, what really are you making? Is it a product or is it some odd portmanteau of digital creative expression?

I understand the temptation to do so. In contrast to engineering, design is a field of subjectivity. There are often no “right answers,” so is the aesthetically arbitrary such a sin? Yes, I think so.

I want the intention behind each decision made to be clear. If there is a pixel on the page, there should be a point to the pixel being on the page. And not only a point, that point should be directly tied to the function of the product. Form follows function, products are designed to be used, and although I will admit my love for abstraction as both an engineer and a designer, that should never overtake functionality.

To make it clear what I’m talking about, GitHub offers a good critique. One thing they do is they treat both organizations and users as the same conceptual model. If you navigate to an organization page, it shows a similar layout to that of the user page. My guess as to why is that they’ve made the engineering decision to share data models between the two, but regardless the reason, the question I’ll ask is whether a user and an org should be treated the same?

Are the functions that a user page serves the same that an org page does? If the answer should be yes, we can call GitHub’s data modeling both a clever engineering solution and design decision, but I’m not convinced as to my own yet.

Somewhat oddly, this pattern of shared data modeling reoccurs several times through the UI: pull requests treat both commits and comments as events in a timeline and even issues and pull requests are treated the same in several instances of the product. So while I don't know yet as to whether these paradigms are the right one or the wrong one, what I will say is that the design I seek to make is one that is absent of abstraction and only seeks to serve the user.

There are three principles I will adhere to:

  1. Form follows function — products are meant to be used.
  2. Remove what doesn't add — make every pixel count.
  3. Less is more — do few things and do them well.

I’ll explain more as to the decisions that motivated the preview you see below later, but for now, enjoy a quick peek into what we’ve built thus far.

 

Thank you for reading
—baepaul.