The Case for Web Browsers

Everyone loves to hate web browsers. There are many good reasons to hate them. But browsers are also great in a lot of ways! Browsers may not be the slickest or sexiest applications, but ultimately they are the most trusted and reliable platform both for users who are exploring the internet, and for developers who are building it.

Here are some reasons that browsers are great. I’ve divided this list into 1) why they’re great for users, and 2) why they’re great for developers. The goal of this list is to explore concepts and patterns that can be copied from web browsers and used in other applications, to perhaps steal some of the browser’s market share. :)

User experience

Browsers have tons of usability and quality-of-life features that users like. Some of these are features that nearly every application ought to have, and a web browser guarantees that you’ll always get them for free.

Universality

For a user, a web browser is a universal client for the internet. This universality is the core of its appeal: if you want something from the internet, you can open up your browser and get it there. There is almost nothing a browser can’t open!

Browsers can be used to view static content or files: various document types (plaintext, hypertext, pdf, json), images, videos, audio. In fact this used to be the whole internet. The original internet, Web 1.0, was just these static files, interconnected through hyperlinks. A web browser as a full internet client just had to be able to display every content type.

Of course browsers can also run programs, of various degrees of complexity. Whether it’s a little bit of dynamic content, or a full-fledged application, browsers can run it. This makes it a full internet client for Web 2.0 as well.

As an extension of this universality, browsers offer convenient access to a search engine. Good quality global search is one of the biggest quality-of-life features for a user in any application. Whole-internet search engines don’t really distinguish between content types; if you search something on your favorite search engine, you get links to blog posts, pictures, online games, web apps, Youtube videos, scholarly articles, social media sites, and so on; so again, a viable internet client needs to be able to handle all of these things.

Pages and navigation

One of the most powerful features of browsers is the navigation bar. There’s so much great stuff packed into the navigation bar; this is my opinion of course, but I believe every application ought to have a navigation bar or something similar.

The navigation bar consists of the address bar plus the forward and back buttons. This is based on a simple but powerful abstraction: the notion of “locations” in an application. The address bar shows the canonical “place” where you are; in principle, if you paste that address back into the address bar, it should always take you back to exactly the same spot (i.e., application state).

Dividing up application state like this into discrete “locations” also means you can easily store browsing history. The browser stores this history in a stack of recent visited pages, which you can navigate up and down using the “back” and “forward” buttons. It also stores a long-term history of all the pages you’ve ever visited. This is super useful because it’s integrated into the search bar, which can auto-complete your search by guessing something from your history, and take you to the page you want without even having to go through the search engine.

Browsers also let you “favorite” or “bookmark” pages, to save or conveniently access pages with certain significance. I find that the search bar autocomplete is generally good enough that I don’t need to use those, but it’s another example of what you can do with these powerful abstractions.

All of these features (locations, navigation stack, forward and back buttons, history, search autocomplete) work together in such a beautiful way that using an application that doesn’t have them feels intolerable.

Browsers have gone through a trial-by-fire, and older versions famously added unreasonable amounts of toolbars that cluttered up the screen, and after this, browsers tried to prune away as much clutter as they could; Google Chrome nowadays doesn’t even show you a menu bar by default. But the navigation bar has always stayed because it would be absurd to remove something so useful.

Browser with too many toolbars

Default Google Chrome (no toolbars or even menubar)

(For compactness, the address bar doubles as the search bar; these two uses don’t seem to conflict with each other, so it works, and this seems to help psychologically unify these aspects of the web browsing experience.)

Tabs

Tabs aren’t a particularly interesting feature, but it’s useful to note that “I want multiple copies of this thing at the same time” is pretty popular, and also combines well with other features (separate navigation stack, shared all-time history).

Plugins

Browsers have an extensive API for plugins / extensions that can modify your experience or add arbitrary functionality. This probably isn’t a great thing for every application to have, but the idea that you can simply change certain behaviors of an application, and of course the existence of a large library of plugins that actually do so, is at least interesting. There’s almost no such thing as, “Well, a browser can’t do [XYZ]!” because you can probably make (or find) a plugin that does XYZ.

Developer experience

Web browsers also have a ton of features that make them developer-friendly.

Universality

Browsers have a kind of universality that benefits developers too: they are basically a virtual machine that has an implementation for just about every platform. This makes them attractive to both professional developers who want to maximize their reach, and noob developers who only want to learn one language / platform.

In theory, browsers differ somewhat in their implementation of this virtual machine standard, but the maturity of tooling around the Javascript language (e.g., transpilers like Babel, bootstrapping tools like create-react-app) papers over any such differences nicely. This means that Javascript applications have really achieved the “write once, run anywhere” gold standard that made Java popular in the 90s and early 2000s.

Sandboxing

A useful aspect of this virtual machine is that it provides good sandboxing– sensible limits on what an application is allowed to do. Each page has its own isolated execution environment and local storage (cookies, client-side databases, etc). Data can be shared between pages of the same app (i.e., same domain), but is isolated from other apps.

Importantly, apps running in the browser are also blocked from accessing the user’s filesystem. Every access to the filesystem requires manual approval through a dialog box. This means users can open any app without worrying about their computer getting hacked; there’s no way for web apps to execute arbitrary code or take control of your device. This removes the element of trust which is needed when you install software directly on your machine.

Distribution

Browsers offer unparalleled ease of software distribution. This is largely a function of the previous two points (a universal virtual machine with sandboxing).

A browser is a fully-featured managed runtime environment that every user already has pre-installed. An enormous amount of dependencies are available by default, including GUI elements (DOM, CSS engine), HTTP handling, advanced data type “primitives” (Array, Date, Number, etc.) that can easily handle almost any use case. This means that developers can ship very small application “binaries” that are just a few 100 kB of javascript; most of the heavy dependencies are part of the runtime.

This makes distribution so easy that developers don’t even consider it as a problem anymore. The whole application gets downloaded when you load the web page. It happens instantly and automatically. “Installation” isn’t a thing; you re-download the app each time you want to use it.

This also makes software updates trivial– just refresh the page. Users don’t need to be notified when an update is ready for downloading; they probably won’t even know that there was an update.

Compare this to the traditional software distribution model, where the user goes through a cumbersome process to download an application, then install an application, then open it up. This whole process is streamlined into a one or two second page load.

GUI programming

Let’s face it, any application that isn’t exclusively used by developers is going to need a GUI. Frankly, I don’t actually understand why web browsers have totally cornered the market on GUIs. The prevailing opinion seems to be that HTML+CSS is easier to write than a component library like Qt, GTK, or Java Swing. This is probably because of the Inspector tool (next section) rather than anything to do with HTML+CSS itself. However, suffice to say that browsers offer a straightforward way to build complex GUIs in an application, which is a must-have for any serious applications platform.

Developer tools

Modern browsers come with a powerful suite of developer tools, which are easy to use and accelerate many otherwise difficult aspects of application development.

Browsers have a built-in interpreter shell (“Console” tab), where you can run arbitrary Javascript code. Additionally, there is a built-in debugger (“Sources” / “Debugger” tab), which tracks the actually executing code in your application at all times; you can set breakpoints, inspect state, and bind variables to the console to run arbitrary code against them. It’s hard to think of another software platform where this level of debugging and introspection is not merely available, but built-in, native, and available through a convenient GUI.

The GUI itself is also inspectable (“Inspector” / “Elements” tab). You can easily check the properties of any element and what part of the screen it represents, edit them in place, and see the changes live, without restarting the application. Again this is unmatched (as far as I know) in any other platform’s development workflow.

Finally, the browser keeps a log of all network requests and responses (“Network” tab). You can edit requests, resend them, and copy them into other formats (e.g., cURL). Every distributed application benefits from this! Again this is built into the platform and available in real-time through a convenient GUI.

Summary

Clearly it’s useless to complain about how web browsers are eating all software without seriously considering all the great stuff that browsers offer. Browsers didn’t take over by coincidence or accident; a browser is a good, mature applications platform. They offer a huge amount of desirable features, fix common programming problems and annoyances, and are so ironed out that a babel-transpiled javascript program is likely to run basically anywhere you can think of putting it.