A brief history of the Web and JavaScript: Part 2
How JavaScript became what it is today. Read to understand the complex landscape of JavaScript frameworks and tools.
Hi Friends,
This is part 2 in a series about the history of the web and JavaScript. The series is intended to give a brief introduction to the history of the web and to give an understanding of today’s complex landscape of JavaScript frameworks and tools.
If you are new to the newsletter: I write for people that want to understand how tech works. I provide context and simple explanation to common tech concepts and tools. This newsletter is great for individuals or small teams who wants to learn how to architect great modern apps.
Have any questions? Let me know in the comments.
Enjoy… /Eric
Part 1: How and why the web was created.
Part 2: How JavaScript became what it is today. Read to understand the complex landscape of JavaScript frameworks and tools.
Part 3: CSS, pre-processors and UI frameworks.
Part 4: A guide for choosing a Frontend framework.
The early days of JavaScript
The first version of JavaScript came in 1994. It was created at Netscape, which created one of the early browsers, to give websites dynamic behavior. JavaScript could only run inside the browser. In spite of its name, it had no association to Java.
Some of the important features JavaScript has:
Access to the Document Object Model (DOM). When a web page is loaded, the browser creates an object-based representation of the page. JavaScript can access this to dynamically change the web page’s structure, style and content.
Access to the Window object. This object represents a window in a browser containing a DOM document.
An interpreted language with first-class functions. Functions are treated like variables.
Single-threaded and based on asynchronous callbacks and events.
Runs in the browser of the client.
So web pages became dynamic and interactive. Great! But then there was a problem: Different browsers started implementing different JavaScript runtimes, supporting different parts of the JavaScript specification. This imposed the need to modify your code for different browsers if you wanted the web page to behave the same in both. This was the same with CSS and HTML.
Enter jQuery in 2006.
jQuery was created to simplify JavaScript and handle the different runtimes in different browsers. With jQuery you could use one function call and behind the scenes jQuery would implement the different implementations needed for each browser. jQuery also simplified the syntax, making it easier for the developer to program with JavaScript. jQuery is still widely used to this day.
JavaScript becomes general purpose, and bundlers becomes a thing
Then, in 2009, Ryan Dahl had a though: wouldn’t it be great to be able to run JavaScript outside of the browser? so he created Node.js, which is a runtime environment for running JavaScript outside of the browser, making it possible to use JavaScript as a general purpose language. Thus, JavaScript was no longer contained to the browser.
But, as all general-purpose languages, Node.js needed a way to import packages and modules. So Node.js introduced the CommonJS specification, a set of conventions for handling modules in JavaScript. So while in the browser you have to import explicit JavaScript files into the HTML document (and unable to import modules within those JavaScript files), with the Node.js runtime you could import JavaScript modules directly into JavaScript files:
// CommonJS made modules possible
// Create a module by exporting one or more functions from a JavaScript file:
exports.uppercase = (str) => str.toUpperCase()
// import that module/file into another JavaScript and use its exported functions:
const uppercaseModule = require('uppercase.js')
uppercaseModule.uppercase('test')
The module system was so great, that people wanted it for the browser too. And this is the main purpose of Bundlers. Bundlers compile your modularized JavaScript files into one single JavaScript file, a “bundle” file, that can then be imported into your HTML document. These bundlers, among other things, also provides code minimization and optimization, making your code run faster.
I was unable to find out which bundler was the first, but Browserify, which came in 2011, was the oldest bundler I found. Webpack, which is the most popular bundler today, was first released in 2014.
And to manage packages/modules for node.js, npm was created, a package manager for node.
The era of Single-Page web Applications
Aside from creating simple dynamic behaviors, JavaScript also made it possible to develop applications for the web, which are highly interactive websites with states and a dynamic UI.
But creating apps with JavaScript is cumbersome and verbose, and it is hard to maintain large code bases. That is why client-side web frameworks emerged. These provided a standardized way to develop applications for the web. These frameworks allow you to write more declarative code – and sometimes less code overall, reducing the cognitive load of having to solve common tasks yourself. They had features such as:
Reactive states. If you updated a piece of data, the framework would update the UI for you.
Components. Being able to abstract different parts of a web site into components, that can be maintained alone and reused with other components to form a website or app. Organization of your code is a lot simpler.
Single-page-application (SPA) architecture. SPAs do not fetch and render new HTML files — they load the whole application at the first request. They use single HTML shell that they continually update through JavaScript. Each pseudo-page in the app is loaded from data stored in JavaScript rather than making requests to addresses on the web. This decreases latency on the client side (except for the initial load) and gives a better user experience.
While there are many of these front-end frameworks, three popular ones you may have heard of are Vue, React and Angular. The earliest frameworks I could find was Backbone and AngularJS, both being released in 2010. These frameworks were initially made for complex and large applications, but they can also aid with development for small apps as well, at least after you have overcome the initial learning-curve.
Meta-frameworks - A framework of a framework
But the SPA architecture came at a cost. The Search Engine Optimization (SEO) was thrown in the dirt, since all the search engine crawler sees when requesting your website is an empty HTML shell. Meta frameworks was created to deal with the SEO problems of SPAs. Examples are Angular Universal (for Angular), Nuxt (for Vue) and Next.js (for React). The earliest meta-frameworks seems to have been released around 2016.
These meta frameworks are specifically applied to SPA frameworks, and they do the following:
In meta frameworks, views (pages) can be rendered on the server before being sent to the browser. This is called Server-Side Rendering (SSR). This provides more control over where pages were rendered. The pages that needed SEO can be rendered on the server, while those that do not need SEO can be rendered on the client side (faster).
Additional convenience functions, structure, and hooks are added to provide a framework for creating so called “hybrid” apps: apps that are sometimes loaded on the client side, and sometimes loaded on the server side, usually dependent on if the page requires SEO.
Static Site Generation (SSG). Most of these metaframeworks provides tooling to generate a static version of your app (a set of static HTML, CSS and JS files). These are faster to load and can be cached on CDN servers for faster latency. This is often used for sites which are not updated often, such as apps with “static” data, blogs, etc.
So, just to clarify, what is the difference between meta frameworks and full-scale server-side frameworks such as Django or Express?
Meta frameworks are made specifically for specific frontend frameworks (Nuxt for Vue, Next.js for React, Angular Universal for Angular), to make these frontend frameworks perform well with SEO and to provide additional convenience for the developers. Altough the complexity of having to deal with learning a framework of a framework is far from convenient.
SSR in meta frameworks generally happen at page load, not at specific requests made on-demand by the user.
Server-side frameworks like Django or Express are made to create full-scale server-side backends, with HTTP REST APIs, authentication, and so on. To an extent, this can be done in meta frameworks as well, but not as well.
Meta frameworks are getting more and more features, and we can probably see a future where they can even replace the need for full-scale back-end frameworks.
In modern apps, a common option is to use a meta framework for frontend and SEO, and then cloud services like Google Firebase for a server-less backend. This way you don’t have to manage your own servers. Firebase is great as backend-as-a-service, but more on that another time..
Typescript: Making JavaScript great again
The first public version of Typescript came in 2012 and was created by Microsoft. It originated from the shortcomings of JavaScript for the development of large-scale applications both at Microsoft and among their external customers.
TypeScript is basically a compiled version of JavaScript with syntax for writing strongly typed programs. It helps you write consistent code that is less likely to have bugs, which is likely to creep in when writing large-scale applications in normal JavaScript.
This only touches the surface, but a few important Typescript features and properties are:
TypeScript adds syntax for types. Strict mode can be enabled such that types are declared for all functions and variables. TypeScript adds additional types such as interfaces (struct-like) and enums.
Typescript transpiles to JavaScript by a compiler. Errors and inconsistencies can therefore be checked for at compile time rather than runtime, and you can discover problems with your code early.
Better error-detection live in the editor, compared to JavaScript.
Typescript is a superset of JavaScript, meaning that existing JavaScript programs are also valid TypeScript programs.
If you are planning to write a large application, TypeScript is a good choice. It is widely used in large organizations.
State of JavaScript
JavaScript is standardized through ECMAscript standard, which first appeared in 1997 and designed by Brendan Eich at Netscape. The current version is the 13th edition of ECMA-262. The ECMAscript standard is managed and developed by tc39, a group of JavaScript developers, implementers, academics, and more, which collaborate with the community to maintain and evolve the definition of JavaScript.
It is the browsers job to decide what to implement from this standard, and of course they prioritize differently. A good website for seeing what features that are implemented in each browser is caniuse.com.
The frontend- and hybrid frameworks are evolving rapidly. There is a big competitions between these frameworks and every year they release new “groundbreaking” features, promising to revolutionize the field of web apps. These features are often (but not always) related to dealing with the over-engineering features already done in these frameworks previously.
Overengineering and complexity is a real concern for new developers who don’t know the difference between these frameworks and their features, or why their features exists in the first place. If you are new to this field you will feel overwhelmed, confused, and depressed by the complexity and vastness of frameworks and tools out there.
The thing to remember is this: All frameworks are built on JavaScript, and you can definitely just use pure JavaScript to create websites and apps. However, the frameworks does makes it more convenient to create apps, even though you initially have to learn the frameworks specific way of doing things.
But which to choose? Just pick one of the popular frameworks that has a big community and it will be OK. They provide more or less the same features but with different semantics, mental models, and convenience factors. They will all work fine. Just don’t pick an obscure framework where you can’t find guides or support answers on StackOverflow (even if it promises it is the best framework ever).
Here is a great annual survey on the state of JavaScript, where you can see the popularity, happiness, and usage statistics of various frameworks and tools in JavaScript: stateofjs.com
Side note: Turning Web apps into native apps
To make this article complete, I should also mention that there are tools that makes it possible to turn your web app into Native apps on iOS and Android. I have not used these tools personally, but it is good to know that these exist, and can be an option if you want to create apps for different platforms but don’t want do deal with writing the same application in three different ways.
Ionic: A framework for turning React, Vue, or Angular code into native apps.
React Native: Turn React web apps into native apps.
Vue native: Turn Vue web apps into native apps.
Flutter: a framework by Google for building natively compiled, multi-platform applications from a single codebase.
There are probably more tools out there, but these are quite popular.
Thanks for reading!
Want a simple guide for choosing frameworks and tools? This is coming in part 5 of this series. Stay tuned!
If you have any questions, just let me know in the comments.
- Eric