The Inevitability of Atwood’s Law
JavaScript, JavaScript...everywhere
“Any application that can be written in JavaScript, will eventually be written in JavaScript”. - Jeff Atwood, The Principle of Least Power - July 17, 2007
In The Beginning
Over the years as I worked with different programming languages, my aesthetic preferences developed. Like many I started with BASIC but grew dissatisfied with it as I learned more about structured programming. I even received a lower grade in a math class because I chose to structure my code and used GOSUB to call subroutines as opposed to writing spaghetti code littered with GOTOs… like an animal. By high school, I fell in love with Turbo Pascal where I found the structure and order I was looking for all along. I learned C but didn’t really get into it because C++ came along and objects were all the rage. Since I primarily developed on and for Windows, I dove into Object Windows Library (OWL) from Borland and Microsoft Foundation Classes (MFC) along with a smattering of cross-platform C++ frameworks that no longer exist.
During the Dotcom Era, I lived in multiple worlds as the Web took off. I still worked on Windows and used Microsoft’s stack for a while. Active Server Pages (ASP) and VBScript powered several Web applications and sites that I built during that period. However, when Java Servlets and Java Server Pages (JSP) arrived on the scene I found the best of both worlds. I could work on Windows and deploy to Unix. Using IDEs such as Symantec Visual Café and Borland JBuilder and applications servers like IBM Servlet Express (later WebSphere), BEA WebLogic and Apache Tomcat I was in backend engineer heaven! Then, Enterprise JavaBeans came along and after trying to decipher entity beans I went back to servlets and JSPs.
Around 2004 I made The Switch™️. I got into a minor car accident and while I didn’t get hurt, my HP laptop did not survive. I was no longer coding as much at work having shifted into management and those Titanium MacBooks sure did look nice every time I went into the Apple Store. I took the plunge and never looked back. By using Mac OS X, I started to reconnect with the Unix philosophy as I explored getting back into code. I never liked Perl, gave Python the side eye and eventually found Ruby. My desire for rigid structure had lessened over the years and I saw incredible beauty in Matz’ creation. The community was amazing in those days and enjoyed writing Ruby code immensely.
Note: As much as I loved Ruby, I was not a fan of Ruby on Rails. While I did read their blog posts and kept up with what was going on with Rails, I barely touched 37signals’ framework. Initially, I was a big fan of Merb until its ill-fated merge with Rails. I switched to using Sinatra which was a much better fit for my sensibilities. That may explain my affinity for frameworks in other languages that follow similar patterns to Sinatra.
Though I was happy and productive with Ruby, I noticed a lot of Rubyists exploring the new kid on the block: Go. While there were many new Ruby runtimes emerging to address the performance issues with MRI, they all had sufficient issues that limited adoption. For those of us working in cloud computing, Go was very attractive due to its origin and design choices. After playing with it a bit, I declared “Go is a language for grown folks”. Attending the first GopherCon in 2014 was an energizing experience. I fanboyed in front of Blake Mizerany in the hotel elevator. I finally met Matt Aimonetti (creator of Merb) and Bryan Liles in person and had a fantastic conversation over lunch with them. Finally, I experienced for the first time (but definitely not the last) the awesomeness that is Kelsey Hightower on stage as he was the MC for the event. By the end of the conference, I was in love with both the Go language and the community.
Enter Node
Taking this trip down memory lane one might notice that I have yet to mention JavaScript. For quite some time, JavaScript was a necessary evil to me particularly for Web development. For client-side form validation and interactivity there were really no other choices. Since much of my work was on the backend I could just hold my nose when I had to write some JS and then get back to a “real” language.
My grudging respect for JavaScript grew as I shifted back to working on Windows applications. First at a startup and then at Adobe, we embraced the embedded JavaScript interpreter model. This allowed us to more easily update business logic in a lightweight fashion. This then expanded into embedding a browser and building UIs with HTML, CSS and JavaScript instead of the Windows API. This was a powerful pattern then and is almost the default today as evidenced by the adoption of the Electron framework.
On the server side, I was still a happy Rubyist. That was, until I ended up working on the API for Adobe’s Creative Cloud Assets service. Our team had used Ruby for another service internally and repurposed much of it for the Assets API. Our original clients were new mobile applications that generated modestly-sized assets. However, once Creative Cloud became the strategy at the company and we started getting hammered with desktop assets Ruby’s concurrency limitations were plain for all to see. Even though solutions like eventmachine existed, most Ruby gems at the time did not work well with it. After exploring a number of options, we decided to try Node.js.
Our API was deployed behind an HAproxy cluster so we decided to try redirecting a handful of API routes to a Node implementation of those handlers. The results were astonishing! Requests that would bring the Ruby service to its knees were handled by Node without breaking a sweat. Route by route we reimplemented the existing logic and made the swap in production. In a little over a month, we completely replace the internals of our API and the Assets Web application was noticeably snappier.
Despite this success, Node still had its issues. The event loop was a new concept for most engineers and debugging and observability tooling was either immature or non-existent. After too many painful oncall episodes trying to restore service, our team started moving critical components to Go. Around that time, one of the founders of NodeSource asked me to lead engineering. We had built up a good rapport during my team’s Node adoption and he was well-known in the ecosystem. Their product was a Node-specific Application Performance Monitoring (APM) tool. Even though I was more into Go personally at that point, I remembered the pain my team went through with Node and this was an opportunity to address those problems for others.
Working at NodeSource enabled me to experience even more of both the JavaScript and Node.js ecosystems. A portion of our engineering team worked almost exclusively on contributing upstream to Node. We had folks contributing to TC39 and on the Node Technical Steering (TSC). I attended JavaScript meetups and conferences and saw JavaScript being used everywhere. Atwood’s Law was real.
JavaScript Is… Inevitable
JavaScript was born in the browser, evolved on the server with Node and extended its reach to embedded devices and edge networks. New JavaScript runtimes emerged to address limitations in Node. Ryan Dahl, the creator of Node.js, built Deno to embrace modern JS and ES modules as well as “fix” his mistakes with Node particularly around security. In this post from 2022 on the concept of JavaScript Containers and the Deno Deploy product, Dahl declared JavaScript the universal scripting language:
To summarize: scripting languages are useful, but they’re all pretty much the same, of them JavaScript is by far more wildly used and future proof. Thus it makes sense to think of JavaScript as the universal scripting language.
Another JavaScript runtime is Bun, aimed at being a faster drop-in replacement for Node, is being used by numerous companies to build and deliver their products. One of those companies is Anthropic, the creators of Claude Code and providers of AI models such as Sonnet and Opus. Bun (and by extension, JavaScript) is so strategic to Anthropic that they acquired the team to ensure Bun remained a viable technology.
There is no question that JavaScript (and now TypeScript) is the most widely used language in the world. Much of that code is open source and, as such, provided rich training data for LLMs. AI coding tools are now generating even more JavaScript at a breathtaking rate. Next year will mark the twentieth anniversary of Atwood’s Law and it will remain true, with one minor caveat:
“Any application that can be written in JavaScript, will eventually be written in JavaScript by AI”.

