Hartley Brody

Look Ma, No Servers! How Javascript is Changing the Modern Web Stack

Formerly titled “The Rise of the Server-less Web Stack”

Javascript has lots of cool stuff built on top of it now. These days, there are tons of well-worn frameworks that bring all sorts of powerful programming paradigms into the browser.

Want easy object-orientation? Use backbone. More of a functional programmer? There’s underscore, lodash and many others. And I can’t keep up with the latest template rendering libraries, but there are dozens.

Plus ECMAscript 6 is rolling out quickly and with it, some long-awaited language features, syntactic sugar and new APIs.

Additionally, there are a lot of JS SDKs and simple integrations for things like accepting payments (stripe), analytics (mixpanel, customer.io, etc) if you don’t want to write the code or support the infrastructure to do those things yourself.

With all of these features, one can build an entire, bonafide web application in pure javascript. This certainly isn’t a new idea – single-page javascript applications have been around for years.

serverless-web-stackBut what if we take the power of javascript to its logical conclusion – making the entire app live in the user’s browser.

Do we even need to deal with setting up servers and maintaing a separate codebase for a server-side backend at all?

Hosting Benefits

I read a great piece recently on my friend Jonathan’s startup’s “stack” and how they have built their application to live on a simple static hosting service.

I myself just shipped a project that will be entirely hosted on s3, and have collected email addresses from statically-hosted landing pages.

It’s a pretty great selling point to tell your client that their web app can have 99.99% availability and no servers that need to be patched or updated or maintained. Nothing to crash or get hacked or set off someone’s pager at 2 in the morning.

Having an entirely static app means you won’t have to worry about many of the traditional scaling issues and performance bottlenecks that most web apps have to consider if (when!) usage takes off.

Serving static files off disk is trivial to scale compared to CPU- or memory-bound applications. Each client is running their own version of the app on their desktop, laptop or phone, using their own CPU, memory and IO resources, not yours.

Plus it’s fast – your entire application can live on a globally-distributed CDN so it’s physically close to users around the globe, without needing to have servers scattered across various data centers.

Granted, this is all because there are already some pretty great abstractions on top of static file hosting that do the “heavy lifting” to deliver the SLA with that many nines. But those abstractions are so cheap and simple that they’re basically a commodity at this point.

All of these benefits mean that a single developer or small team can get pretty far without needing to have any devops skills at all. Just push your code to a static file host and make sure your domain is pointed to the right place.

Remaining Problems

Okay so building a web app for a static hosting environment has some awesome benefits. But there are definitely some drawbacks to consider — depending on your application’s needs.

Data Persistence
If you need any sort of centralized datastore across multiple clients (ie Users, Accounts, etc) you’re probably going to need a database server and some application logic that lives on top of it.

But you might also be able to use the API of an existing third-party system like Firebase or Parse.

You could leverage the existing API of your company’s CRM or other existing internal datastore. I was able to use a Marketing SaaS app as the “database backend” for my recent client project, by simply sending data from the app directly to their marketing software’s API.

It’s also a good idea to consider whether your app really needs a database at all. Is it really a requirement that users need an account before they can use your product? Don’t collect and store data needlessly.

3rd-Party Integrations
If your app needs to integrate with a third party for storing data, sending emails, tracking user analytics or other tasks, you might need to keep that integration on the server-side if it requires authentication – you don’t want to send API keys or other credentials to the client. But if the API doesn’t require auth or has a client-side integration option, you may not have to worry.

Another problem you might run into is CORS support – if the vendor’s API doesn’t return the right headers, then the client will refuse to send requests to it. But if an API endpoint expects GET or POST requests, a potential workaround is to just use form submissions in a hidden iFrame to send requests without reloading the page. Hack-y, but doable.

Some APIs are specifically designed to accept form submissions, like MailChimp for managing email lists or the the Google Forms to collect arbitrary data in a spreadsheet.

Private Business Logic
This one admittedly has no really good answer. You could run your javascript through obfuscation (renaming variables and functions to meaningless letters) and minification tools, but the instructions and logic are still there if anyone wants to take the time to piece them together.

Having had to read through obfuscated and minifed javascript in a previous job at an ad-tech company, I can tell you that it’s certainly not easy or pleasant to reverse engineer code that has been run through these steps, but it is possible.

So if your app uses any sensitive, valuable or proprietary business logic, it’s best you let that run on the server-side.

Crashes and Bug Reporting
When a 503 happens on a web server, most web frameworks send you a pretty stack trace in your inbox by default. But when building a javascript app, things fail on the client’s machine, out of sight of your web server’s logging features.

It’s important to consider how things might fail — network being unavailable, unexpected input or result of computation, etc — and figure out if or how the exceptional condition should be reported back to your system, and also how to communicate about the exception to the user.

Heavy “Offline” Processing
If your app processes a ton of data, you probably don’t want that happening synchonrously on a web server during the request-response cycle anyways.

With javascript, the risk is that you’ll hang the user’s browser if you’re doing expensive calculations on the main thread.

On the server, you might do something like kick off some offline job to do the processing and store the output or notify the client when it’s done.

In javascript, there is a pretty simple Web Worker API that’s widely supported. If you need to do heavy rendering or data crunching, it’s worth taking a look at Web Workers.

There obviously still some drawbacks to the “server-less web stack” and servers certainly aren’t going away any time soon. But building a server-less application has some really cool benefits.

You should consider if it’d be a good fit for your next project.