Blog Insights
JavaScript is Taking Over the World, and It’s Got Us Too

JavaScript is probably the world’s most widely deployed programming language. It’s easy to use, and its features and community make large projects manageable. JavaScript is a central piece of web technology. It’s the only programming language allowed to run in browsers, and it has a sizeable presence on servers thanks to node.js. This language is the essential foundation for any interactive experience out there. It powers widgets like search boxes and filters, and everyday applications from email clients to radio stations. We at Forum One are focused heavily on what’s possible on the web today, so it’s no surprise that we’ve modernized how we build and deploy our JavaScript projects. We’ve made a list of must-haves for building applications of any size, and want to share how we build robust and dynamic projects.

Code Quality

We want to be 100% certain that our code is ready to ship, whether we’re working on the first line of code or the ten thousandth. To ensure this, we’ve adopted TypeScript and TSLint as our quality checking tools of choice.

TypeScript

“The main purpose of a type system is to reduce possibilities for bugs in computer programs by defining interfaces between different parts of a computer program, and then checking that the parts have been connected in a consistent way.” – Wikipedia: Type system.

Type checking is an important part of any large-scale project, whether you realize it or not. All code makes assumptions: mathematical functions accept and return numbers, regular expression functions work on strings, and ReactDOM.render() accepts a ReactElement<P>, an Element | null, and an optional callback in one of its eight overloads. Why keep track of this yourself when a computer can do it for you? Since 2014, we’ve been working with the National Assessment of Educational Progress (NAEP) to build reports for the Nation’s Report Card, which is the largest ongoing assessment of what U.S. students know and can do. And we’ve been building these reports with TypeScript. We retrieve NAEP data from an API, and having type definitions for this data has been a real life-saver. The records the API returns have varying shapes based on what kinds of comparisons we ask the server to do. A data comparison between two jurisdictions will have different fields than a data comparison between two years, and the TypeScript compiler will refuse to allow code that mixes up the two kinds of results. As a result of this type checking, we’ve had to fix fewer bugs overall since many were prevented from even being written. This success is driven by both the language and its community. We owe a huge debt to the DefinitelyTyped project. It has been around for a long time, and is now the official source for type definitions of npm libraries. The community has produced thousands of definitions for libraries like d3, React, jQuery, and more. These serve as the bridge between our own TypeScript code and the broader JavaScript ecosystem.

TSLint

“The lint utility attempts to detect features of the named C program files that are likely to be bugs, to be non-portable, or to be wasteful.” – the lint manual

Unsatisfied with mere type checking for our projects, we added TSLint to our bug-catching toolkit. The term “lint” generally refers to an undesired bit of program behavior that might be allowed by the language but is nevertheless considered suspicious or potentially error-prone. TSLint covers a wide range of possible lints, from stylistic concerns like variable naming conventions and proper curly brace usage, to safety concerns like preventing access to eval() or the with statement, to even more sophisticated analyses like object model coherence. Linting becomes increasingly important when working with a team of developers. As with writers, all developers come to a project with different styles of coding which, in and of itself, is not bad. But the ultimate goal of a solid codebase is to have some semblance of standardization. We recently wrapped up work on City Health Dashboard for the Department of Population Health at NYU Langone Health, which is a complex project that looks at 37 health metrics across the 500 largest cities in the United States. It enables users to compare metrics between cities, look for correlations between them, and see maps that visually show variances by census tract for any given city. With a sizable team of developers contributing code to the project, having linting in place helped to ensure that the formatting of our code was consistent, which in turn allowed us to focus on the substance of pull requests. By enforcing good coding guidelines with TSLint (and making it part of our build), we ensure that all code is written in a way that we believe to be robust and maintainable.

Build Tooling

JavaScript applications have a lot of dependencies. In addition to third-party libraries, applications depend on non-code assets like images. Managing all these dependencies requires playing well with both users’ browsers as well as the content delivery networks that are caching these applications.

Enter Webpack

Webpack is a build tool for the modern Web. It reads in your application sources, analyzes the dependencies, and outputs files containing only the code needed to run. This system is extensible: we are able to add processors (called “loaders” in Webpack-speak) to handle bundling style sheets, images, and even things like CSV files. We have a default configuration for all projects that ensures a good developer experience along with build output that follows best practices. For example, when it’s time to do a production build, we automatically optimize images.  This configuration evolves with our needs. We’re looking at integrating pre-rendering plugins for better search engine visibility, and tuning build times on large projects by using multi-threaded builds. (As it turns out, an easy way to speed up doing a lot of small tasks one-by-one is to distribute the workload. Who knew?)

In the Browser: React

“React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.” – reactjs.org

React is a declarative framework for web applications. Instead of using view classes or templates to build up an interface, React expects a description of an interface. The rendering engine (the reconciler, in React parlance) then uses this description, compares it to the current state on the page, and then updates the page on an as-needed basis. Because React is only a user interface library, its maintainers are able to make it perform as efficiently as possible while allowing developers a great deal of flexibility to handle their applications’ logic and data sources without needing an extra integration layer to deal with.

On the Server

One natural consequence of world domination is running on both ends of a web site: the front and the back end. We’ve been using node.js to run a variety of services. The combination of a built-in event loop with an enormous selection of third-party packages makes node an ideal system for implementing webhooks, bridging APIs, or even providing our own. We use TypeScript and TSLint on the server as well to ensure that both halves of our systems — producer and consumer — are communicating consistently with each other. In addition, some of our bigger backend systems are now running in Docker containers. Our automated build systems produce an authoritative image of the server, and the ephemeral nature of containers means that deployments are reduced to a mere restart of the container environment. Thanks to Docker Compose, our local development environment has near-perfect parity with the production stack, surrounded by locally-accessible tools that make it easier to debug or monitor a running server. Services like MailHog or Minio can be run with less stringent protections.

What’s Next?

The world of JavaScript is a bright one. The language and its tool set has helped us take on everything from embedded data tools to large-scale web applications. The future of JavaScript is even brighter. Peeking over the horizon is a world of general-purpose edge computing with tools like CloudFlare Workers and Lambda@Edge, next-generation APIs powered by GraphQL, and more. We’re excited about what the future holds and how we can use it to power our next solution. If these sound like the right tools to meet your needs, get in touch! We’d be happy to share our expertise to bring your organization forward.

Written by

Are you ready to create impact?

We'd love to connect and discuss your next project.