2025-11-09 | 4 min reading
These are some thoughts that came after watching the video Architecting LARGE software projects by Eskil Steenberg.
Note, I only covered what caught my attention from a Front End perspective, not the whole video.
The Structure
We are optimizing for:
- Dependability
- Extendability
- Team Scalability
- Development Velocity
In general agree, when he talks about Team Scalability and people don’t interfere with each other, I call this Orthogonal Tasks.
Orthogonal, as per in telecommunications, when you have orthogonal signals that allow the transmission of multiple signals over the same channel without interfering.
This is tot…
2025-11-09 | 4 min reading
These are some thoughts that came after watching the video Architecting LARGE software projects by Eskil Steenberg.
Note, I only covered what caught my attention from a Front End perspective, not the whole video.
The Structure
We are optimizing for:
- Dependability
- Extendability
- Team Scalability
- Development Velocity
In general agree, when he talks about Team Scalability and people don’t interfere with each other, I call this Orthogonal Tasks.
Orthogonal, as per in telecommunications, when you have orthogonal signals that allow the transmission of multiple signals over the same channel without interfering.
This is totally doable in my opinion and can be achived by having a clear distinction from what is an Orthogonal Tasks and what’s not, plus a little planning on the project structure to prevent conflicts.
Reducing Risk
- Changing platform
- Language implementation
- Changing hardware
- Changing priorities
- Losing people
If you write software that have to live 20 years….
For the FE source of risks I would add:
- packages
- runtimes
- browsers
Packages:
- frameworks
+ react
+ next
+ bootstrap
+ tailwind
- tooling
+ sass
+ postcss
+ webpack
+ storybook
+ jest
These are some of the most popular packages, and none of them is in a stable or low-risk position today. They are all or changing and breaking APIs or having competitor projects comming to deprecate them.
Runtimes:
Runtimes fall into the category Language implementation mentioned by Eskil and yes, when they break compatibility it’s a disaster, see the CommonJS vs ESM case.
But it doesn’t end there, runtimes also affect in cascade the whole ecosystem, forcing package maintainers on multiple format and extra chores.
Browsers: In this case, the threat is in the fragmentation.
Fragmentation of browsers and OSs, each one with its own peculiarity.
For example, we may have the same browser, same version, but under different OS behaving differently. Sometimes you can mitigate with polyfills, sometimes you’ll need an ad hoc strategy.
See the case of keydown event on mobile returning code:229, breaking keydown events, or Safari in Private mode breaking localStorage.
Many small chances of failure
Many small chances of failure == a big chance of failure
A lot of little things that might be easy to fix, if you have enough of and they happens frequently enough…
We’re basically describing npm update.
For this, the recipe is:
- use
nvmandnvmrcto lock the node version - use
save-exact=truein your.npmrc - run periodically
npm outdateand do one update at the time.
Dependable Language
Language: C89 - Dependable C
So I’m a C programmer. I use C89. It is the most dependable language you can have. Um it will compile everywhere. It will last forever. It you know works works works works.
Eskil talks about C, but what about Node.js and JavaScript?
Well, JavaScript within the browser is not too bad actually. Yes, you have incosistent behaviours, but overall, the APIs tend to be stable, especially for old stuff.
The elephant in the room is Node.js and all the packages that break, break, break.
Continuously.
Today it’s because they migrate from CommonJS to ESM, tomorrow is because a cooler package get in town.
Packages are the most unstable part of the ecosystem; reducing the package surface should be one of the main imperatives for project stability.
You should wrap your platform layer
The idea here is that anything you don’t own, which is the platform, you should not talk directly. You should make a wrapper around that, and again even if you use something that is online and you know open source and you know generally is really good you still don’t control that, right?
This is possibly the most precious insight of the whole talk as it’s telling something that we know but it’s difficult to digest, that is: don’t trust the framework, don’t trust the browser, don’t trust the OS.
Wrap all the next/route, next/link, wrap the scroll bars in the browser, wrap the keyboard.
Insulate yourself from those hostile environments that are packages, browsers and OSs.
Write a test application. Demo App
Eskil mentions this in the context of porting the code from one platform to another, because with a demo app you have a small surface and you gain speed in debugging.
But you can also use a demo app as a canary to check if npm i next@latest breaks anything without waiting 50s for npm run build and it’s the perfect test bed to prototype.
Plugin Architecture
The core here um doesn’t actually have an UI, doesn’t do anything. It’s just a core, right? That you can, you know, read in plugins and then you can access the plugins
I didn’t made my mind yet on this, but I feel this concept is intriguing, especially when thinking about all the time in React and Next.js you have a page full of APIs calls and data not in sync in useState.
I feel a core would allow to decouple the whole business logic from React and Next.js. Maybe MobX, Redux and Reducers are just a partial attempt in this direction.
Write tooling
Write tooling!
- Recorder
- Playback
- Python API
- Logger
- Visualizer
- Simulator
The label I put on this is Observability.
At some point, when things are messy and complex enough, you will want to observe what’s going on in your system. You will want to isolate and reproduce to fix a bug.
Maybe this can be as simple as dropping in New Relic, DataDog, or Sentry. Or maybe you’re going to add a debug to your system. Or maybe you’re going to have an event based architecture which is going to allow you to record what’s going on and replay.
Anyway, we start to think about these kinds of problems late, when things are already settled and changes are painful.
Thought for the future, what would be useful to record?
- user events like clicks, typing
- API calls with the payload sent
- page changes
- errors
How are you going to implement?
- debug and flags
- observability services
- supporting architecture
Last thoughts
I warmly recommend watching the whole Architecting LARGE software projects.
As mentioned, what covered is just a subset and the video is full of goodies like Information and Capability, Format Design, and Semantic vs structure.
Instead, if you want to investigate more Software stability the FE side, you can read Thoughts on APIs stability, and Thoughts on broken vs wrong.