I often see people discuss embedded development and web development as being two opposite sides of the spectrum of software engineering: one is low-level and hardcore, and the other one is high-level and almost trivial. After more than 20 years working in both domains, I have come to view web and embedded as highly similar—I can use the same approaches in both worlds.
The usual discourse goes as follows:
- Embedded development is complex and open to a select few experienced developers. It requires precise thinking and strict software engineering.
Web applications and embedded systems are both distributed systems
In an embedded system, you have sensors, actuators, multiple microcontrollers, often a Linux system, increasingly standard cloud connectivity, and over-the-air updates. In a web application, you have client browsers, servers, storage services, databases, caches, logging, and monitoring. These components need to communicate to present the user with the desired functionality.
Furthermore, these components need to be monitored and maintained. The system is usually permanently online. Building software updates is intricate; distributed and update processes often require orchestration. Debugging at scale usually requires monitoring and log collection, as interacting with any individual component is often impossible.
Web and embedded software engineering is remarkably similar
At a more technical level, the software and architecture of web and embedded systems are built on the same underlying abstractions and must fulfill similar constraints.
At a higher abstraction level:
- The user application is implemented by a distributed system
- Actors communicate over a network, using a variety of protocols
- The application is long-lived, requiring special attention to error handling
- Most actions require a sequence of asynchronous steps
- Deployment at scale requires synchronization because of interdependent components
- Because of their complexity, systems often exhibit emergent behavior
- The execution environment is remote (local web development usually requires some docker setup; embedded development requires some playground for the actual sensors and actors)
- Performance is an essential component of system design due to power, real-time, response time, or cost constraints
The similarities are even more striking once we zoom in on the code level:
- User and hardware interaction often require complex behavior due to UX design,
- Most of the code is sequencing asynchronous steps
- There is no happy path. Because at least part of the system runs without direct user supervision, we need at least restarts and error logging
- The same software patterns prove very effective:
- state machines, promises, or coroutines
- event-driven development
- structured logging and observability metrics
- structured RPC IDLs
- monoidal state handling (state reducers like redux store)
- Instrumentation for debugging is extremely useful, yet can quickly impact runtime behavior
- Many issues can only be caught in production (or in-field testing). Mocking only goes so far due to the emergent behaviors mentioned above
There is a lot to learn from both fields
I have learned a lot from working in both domains and have carried over not just ideas but actual code and tooling. Framing embedded development as low-level systems requiring advanced skills versus web development as a free-for-all, low-hanging fruit obscures how similar they are.
Both are hard to get right, both benefit from a holistic systems approach, and actual code and tooling carry over surprisingly easily.
I plan this to become a longer series that explores what I learned in my career in web and embedded, so stay tuned!
(cover image: ranzino flickr)
Oldest comments (11)
Anybody here who has been working in both fields?
I work in both fields, I often build ESP32 applications that serve react pages. I don’t have a lot to add to the convo, it’s hard to be objective as I learned the 2 skills in parallel. WEB is probably easier to debug generally, but frameworks on the embedded side are certainly making the workflows more and more similar. AWS freeRTOS SDK for example, feels like a batteries included web framework and I can do a lot of copy/paste style dev, and on the other hand I write the odd web app that ends up using all the binary operators in JS so I guess there are potentially lots of similarities. I do spend time wishing there were ex. await or handy string operators in C, so at times the difference is pretty stark. freeRTOS has queues and async-ish APIs but it’s never quite as handy as those in JS, and the bugs that come up are sometimes very hard to catch. On the other hand there is no tidy defer() JS paradigm, which is common sense in C. I think after typing this out I’d say yah, no, they are very different, but the authors point stands, there are more similarities then one might expect, and the similarities are growing IMO. Reasoning about memory allocation, or groking peripheral protocols is not as hard or exotic as people make it out to be at times, so I think the skills that an advanced web dev has are CERTAINLY going to apply to embedded dev.
I presume you've built very little on the web.
I don't even know where to start with how arrogant and ignorant that statement is.
Web development involves DNS configs, often email configs, web server interactions, databases and half a dozen languages on various operating systems and hardware.
And that's without discussing application/website features and functionality that have to work across a million screen sizes and device models, and have to load incredibly fast while at the same time running a dozen scripts on page load so the marketing team doesn't lose their minds.
And them, you try coding html/css for emails and see how far you get when the client wants it to specifically work in outlook 2003 on a five year old laptop.
None of this even touches on large scale sites with load balancing, auto scaling, cross-timezone interactions and ecommerce integrations for payment services and shipping services and a million other things.
If was allowed to curse on here, you'd hear a mouthful of it right about now.
Just stay in your embedded world and don't speak of web dev again.
I am saying "the usual discourse", I also disagree with that statement :) I've written enough web software over the years to know how complex it is. If anything, I think overall web applications are much more complex than most embedded applications.
I know I probably didn't chose the clearest words, but I hope you are not this rude in all your conversations, and give your interlocutor the benefit of the doubt when possible.
@ravavyr You completely missed the point, which the author graciously replied to you with already. He was making a claim about what he's seen as "the usual discourse", to which the entire point of his article was to propose an antithesis to that discourse; or if not an outright antithesis, at least adding context, nuance and perspective. In other words, he also disagrees with the position that you disagree with so vehemently. In other other words, you are griping at someone for agreeing with you.
You write "I don't even know where to start with how arrogant and ignorant that statement is".
That is ironic, as the actual arrogance and ignorance is demonstrated by your response, none by the original article.
I'm guessing you just skimmed the article and looked for evidence to confirm your bias/attitude. In that case, read more carefully, especially before spouting off at the mouth (keyboard).
If you actually read the article through though, then frankly you have a serious comprehension problem, and should definitely enact a habit to restrain your reactions, and work to understand grammar, context and intent more fully.
You seem like a lovely person.
It's clear you didn't read the full article. Don't take things so personally and read the whole damn article and don't be so damn rude. You completely missed the point. If you're ego is that fragile don't read or post.
Couldn’t agree more. I work for a states office of technology and there are feature’s within apps that are highly complex. Forced to be well thought out and executed. Tied to multiple other apps and features throughout the state. Some basic things are trivial sure. I might also guess there are trivial things on the embedded side as well.
nice article. I have been in web and embedded development and I was surprised when I was able to bring stuff from one to the other, when they look so different on the surface.
Example: I could not believe when other devs were proposing to use FSMs (state machines) on web, while they are so fundamental on embedded. I now see the need is there, however I did not see it from the start.
I'm curious as to what tools you used in common from one to the other, besides VS Code or your fav IDE.
Looking forward to reading more of your series!
I know people compare the fields because I’ve done this in the past.
I think it’s unfair to compare the two. They have similarities but are ultimately very different.
I’m deep in the embedded world and program in: Verilog, system Verilog, C, CPP, Assembly, python, bash… etc. I have a degree in EE but have migrated down the Silicon-based IP path.
It’s all about the requirements! For me, I build embedded systems. Sometimes I need different communication standards (I2C, SPI, UART), sometimes I need to reference pre-existing hardware (peripherals; and I need to adhere to their requirements), sometimes my system doesn’t meet timing (requires me to rethink every line of code to determine what is the problem), and sometimes nothing works at all (software and hardware).
Requirements between the two fields can contain many parallels but need different skills and different thought-processes.
People are diehard about their fields and I get it… but people like @ravavyr are the problem. There’s no reason to freak out and try to defend your profession like you’re under attack. If anything, someone should be getting confidence to try something new from this post.