29th July 20265 min read

The language stopped mattering

RapidNative's open source page: tinbase, Lifo, ReactNative.run, ORCHD and jetplane

There are five open-source projects on our open source page now. The newest one is ORCHD, a multi-tenant workload orchestrator, and I wrote it in Go.

I do not write Go. I have been doing JavaScript and TypeScript for years, React Native for over a decade. Two years ago, "let me build this in Go" would have meant a quarter of ramp-up and a codebase I would be slightly embarrassed by. This time the language was not even in the top five hard problems.

That is the thing I want to write about. Not the project. The fact that the choice of language has quietly stopped being a constraint on what I am willing to start.

What is on the shelf

  • tinbase — a Supabase-compatible backend without Docker. One process, real Postgres, and the official supabase-js SDK works unchanged. TypeScript. Still alpha.
  • Lifo — a Linux-like OS that runs anywhere JS does. A clean-room reimplementation of Unix in TypeScript, in a browser tab or a Node process. Not a VM, not an emulator.
  • ReactNative.runbrowser-metro, which bundles React Native entirely in a Web Worker. Any npm package, Expo Router, real HMR, no build server.
  • jetplane — a Metro plugin and a thin dev server, so same-dep projects share one transform cache instead of each carrying their own.
  • ORCHD — per-tenant workloads, each with a hostname, asleep when idle, awake on the next request. Go.

Four of them are TypeScript because that is where the problem lived. One is Go because that is what the problem wanted.

Why Go, and why that is not a big deal

ORCHD needed to be a long-running daemon on a Linux box that holds an HTTP request open while a container boots underneath it. That is a single static binary, real concurrency, and a standard library with a good HTTP server. In Node it would have been a process I have to keep alive, a runtime I have to ship, and a concurrency story I would be fighting.

So: Go. Not because Go is fashionable, because the shape of the problem pointed there.

What used to make that expensive was never the ideas, it was the friction. Idioms. Error handling conventions. Which of the four ways to structure a package is the one people actually use. Knowing that context.Context goes first and why. That layer is now a conversation away, and it collapses from weeks to hours.

What did not get easier: deciding that the runtime should be an interface with several implementations, that the gateway has to own the wake because only the thing holding the request can wait for a boot, that volumes must be decoupled from instances. Nobody handed me those. That is the actual work, and it is language-independent — which is precisely why the language stopped mattering.

The part I find more interesting: measuring got cheap

Here is the change I did not expect.

Writing a benchmark used to be a small project of its own. Harness, fixtures, a way to run it repeatedly, a way to read the output, a chart if you want anyone else to care. So you did it once, at the end, when something was already slow — and by then the design was set and you were negotiating with your own architecture.

Now I write the harness while I am still deciding. Which means I have numbers early, and numbers early change what you build:

  • tinbase boots at around 59 MB of RAM on its native engine, instead of a Docker Compose stack of a dozen containers.
  • jetplane takes an Expo dev environment from roughly 325 MB to about 40 MB, because the transform cache is shared across same-dep projects. On device we measured a 99.9% cross-project hit rate.
  • ORCHD cold-provisions a workload in ~2.8 s under gVisor, wakes a suspended one in ~0.9 s, holds ~75–85 MB while running, and 0 while idle.

None of those numbers are impressive because I am clever. They are what happens when the cost of checking drops far enough that you check constantly. Optimization stops being a phase and becomes a constraint you carry from the first commit.

And it converges on a shape: one binary. One box. One process. Small footprint. Not as an aesthetic — as the thing the measurements kept rewarding. Every time I looked at the numbers, the answer was "you do not need the extra layer", so the layer never got built.

This is how I am catching up

I will be honest about the motive. The coding world has changed faster in the last two years than in the ten before it, and it is easy to become the person narrating that change instead of doing it. I did not want to be that person.

So my way of catching up is to build things I would previously have called out of scope. A database backend. An operating system in a browser tab. A bundler. An orchestrator in a language I do not write. Not to prove they can be built — to find out what the new floor actually is, by standing on it.

What I have learned so far: the floor moved for syntax and mechanics, not for judgment. What to build, what shape it should be, what to measure, what to refuse to add — all still on me, and it is now a much larger share of the job than it used to be. The leverage moved from typing to deciding.

Which, if you have been doing this a while, is a very good trade.

All five are MIT and open on rapidnative.com/open-source. tinbase is alpha, ORCHD is early — read them as working code, not as products. If you build something on top of any of them, I would like to hear about it.

Best, Sanket