Renaming isomorphic JavaScript?
What you need to know to make an informed choice.
Abbott and Costello’s signature wordplay sketch “Who’s on First?” is one of the most renowned comedic routines of all time. Trying to describe the routine here will do it little justice, you’ll just have to watch it yourself. As funny as it may be, the sketch reveals a crucial fact: names are important. Good names should be self-explanatory, precise and reveal intent. Bad names leave people confused and aggravated and should be avoided at all cost. When we write code, we must always think about variable names, function names, file names, etc. But naming things is hard. Phil Karlton probably said it best: “There are only two hard things in Computer Science: cache invalidation and naming things.”
Since Node.js was first released in 2009, many developers have started discussing and implementing ways to share JavaScript code between the web application server and the browser. This sharing of JavaScript code allows for assembling web pages on either the client or server, with the benefits of faster initial page load times and improved search engine optimization. The name of this approach was coined by Charlie Robbins and later popularized by Spike Brehm as “isomorphic” JavaScript. Such applications are isomorphic in the sense that they take on equal (ἴσος: isos) form or shape (μορφή: morphe) regardless of which environment they are running on, be it the browser or the server.
“Isomorphic” JavaScript also emphasizes that sharing code between the server and the client requires differentiating environment-specific code. “Isomorphism” captures the notion of two mathematical objects that have corresponding or similar forms when we simply ignore their individual distinctions. When applying this mathematical concept to graph theory it becomes easy to visualize. Take for example the two graphs in the following figure.
These graphs are isomorphic, even though they look much different. For starters, they both have the same number of nodes with each node containing the same number of edges. They are isomorphic because each node in the first graph maps to a corresponding node in the second graph while maintaining certain properties. For example, the node A can be mapped to node 1 while maintaining its adjacency in the second graph. In fact, all nodes in the graph have an exact one-to-one correspondence while maintaining adjacency.
This is what’s nice about the “isomorphic” analogy. In order for JavaScript code to run both on the client and server environments, these environments have to be isomorphic, that is, there should exist a mapping of the client environment to the server environment functionality, and vice versa. Just as the two isomorphic graphs have a mapping, so do isomorphic JavaScript environments. For JavaScript code that does not depend on environment specific features, for example, avoids using the “window” or “request” objects, it can easily run on both sides of the wire. But for JavaScript code that accesses environment-specific properties, e.g., “req.path” or “window.location.pathname,” a mapping needs to be provided to abstract or “fill in” (sometimes referred to as a “shim”) a given environment-specific property. Isomorphic JavaScript applications may take advantage of build scripts and tools like Browserify and Webpack, which extract, morph, and package code up into a browser-friendly version.
“Isomorphic” JavaScript, however, has left some confused and aggravated with its semantic ambiguity. Some have raised concerns over the word’s inaccuracy and the barrier it creates for new developers to grasp the concept. Many have suggested alternative names. Michael Jackson, a React.js trainer and co-author of the react-router project, has suggested the term “universal” JavaScript. This term borrows from Apple’s description of app bundles that ran on different CPU architectures (i.e. PowerPC and Intel) and of apps that run on both the iPad and the iPhone. Because of Apple’s usage and the familiarity of the term in everyday use, Michael has had better luck explaining “universal” JavaScript to the developers he’s trained. The term “universal” also highlights JavaScript code that can run “not only on servers and browsers, but on native devices and embedded architectures as well”. This gives the name a distinct flavor and helps in expanding the discussion beyond the traditional web application client-server model.
Yet others have suggested names like “shared” or “portable” JavaScript to stress the commonality of the code running on the server and the client. “Cross-environment” and “Full-stack” JavaScript have also come up in this naming discussion. Each of these names has its own merit, and it’s exciting to see the desire of the JavaScript community for good names. For our upcoming O’Reilly book we’ve decided to continue using isomorphic JavaScript. It’s a term that emphasizes the right things for us, has become part of the vernacular and is better known than what’s been suggested so far. But what do you think? Please email us with your suggestions and help us name our book: Jason Strimpel jstrimpel.oreilly@gmail.com and Maxime Najim mnajim.oreilly@gmail.com.