Skip to content
All writing
A React frontend receiving live updates from Node.js services connected to MongoDB and Ethereum

Owning a Real-Time Frontend at Laminar

A frontend can be neatly laid out and still leave someone unsure what they are looking at. In a system that keeps changing, presenting a value also means communicating how much the interface knows about it.

From October 2020 to March 2021, I was an Intermediate Full-stack Developer at Laminar. I owned the React and TypeScript frontend for a market-making financial services platform for cryptocurrency trading. We used TradingView for the trading UI. The frontend communicated with Node.js services over uWebSockets. The backend used MongoDB and integrated with Ethereum through the Web3 SDK.

Market-making supplies liquidity: making assets available for others to trade, commonly by offering to buy and sell at quoted prices. That puts changing information at the centre of the software's job.

React described the surrounding application, TradingView provided the trading UI, the socket connection carried updates, and backend services connected stored data with an external network. The boundaries between those responsibilities are a useful way to think about the work.

A live connection changes the frontend's job

With a conventional request, the application asks a question and handles a response. A live connection also lets the server send information while the person does something else.

The WebSocket API provides a two-way connection between browser and server. At Laminar, communication with Node.js services used uWebSockets. The transport explains how the pieces connect; the application still has to interpret the messages.

Does a message represent a complete value, a change to something already loaded, or information for a different view? The frontend needs a model for those questions before React can render a useful result.

My preference is to give message handling a clear boundary. Components should work with data that makes sense to the interface, rather than each component inventing its own interpretation of incoming messages. That keeps presentation decisions separate from the rules for incorporating an update.

Connection state and data state are different

An open socket tells the application something about the connection. It does not, by itself, say that every value on screen is current or complete.

For any live frontend, I would ask how the interface behaves before initial data arrives, during an interruption, and when communication resumes. A reconnect is a reason to reconsider what the client knows. It is not automatically proof that its previous state has caught up.

The design can preserve useful information while making uncertainty visible. "Still connecting," "last known value," and "ready" communicate different situations. Treating them as distinct is a good starting point.

The data layer needs enough information for the UI to make an honest claim. A component that only receives a value cannot explain whether it is awaiting confirmation or came from an earlier connection.

React should not inherit every transport decision

I also want a deliberate boundary between receiving information and deciding which components need to update. A stream can produce more activity than any one view needs. Sending every incoming message through every component creates unnecessary coupling between network traffic and rendering.

The browser's standard WebSocket interface does not provide automatic backpressure: an application can fall behind when messages arrive faster than it processes them. MDN documents that limitation. A fast server does not remove work on the client.

Depending on the data, useful approaches might include narrowing subscriptions, combining display updates, or separating background processing from rendering. The choice has to preserve meaning. Dropping an intermediate display value and dropping an instruction are very different decisions.

Ethereum is another boundary

The backend used MongoDB and integrated with Ethereum through Web3 during my time there in 2020 and 2021.

Ethereum integration adds another system to reason about. JavaScript libraries provide a convenient interface to Ethereum nodes and their APIs, as explained in Ethereum's JavaScript API documentation. The library simplifies communication; it does not make every asynchronous operation equivalent to an ordinary local function call.

At the frontend boundary, I would want service responses to describe what is known, what is still in progress, and what failed. A person using the product should not have to infer those distinctions from low-level SDK behaviour.

For external integrations, translate the dependency's behaviour into states the product can explain without forcing the user to understand the backend's implementation.

What frontend ownership means to me

Owning the frontend means taking responsibility for the connection between what the system does and what the interface communicates. It includes layout and interaction, but also the data model, integration boundaries, and behaviour when information is incomplete.

Laminar put that responsibility in a real-time financial software setting. The engineering questions it raises remain relevant to collaborative editors, operational dashboards, and other applications that keep receiving updates after the first render. A useful interface gives changing data a clear meaning.

Further reading

See my Laminar role and full work history.