A List Apart


Illustration by Kevin Cornell

Even Better In-Browser Mockups with Node.js

Designing in the browser has all sorts of benefits, like producing more accurate, comprehensive results and removing the extra step of converting from image file to markup and CSS. But even sites designed in a browser still require pasting in content, faking interactions with the server, and creating placeholder JavaScript that isn’t usable on the live site.

Article Continues Below

Wouldn’t it be nice if we could go from just designing layouts and interactions to designing the whole client side of the application during the same process?

This is where Node comes in.

Node.js is a server-side JavaScript platform. It isn’t a web server, but it allows you to easily create one. It also lets you create utilities that run on web servers, like setup and minification utilities and general-purpose command line tools.

Node started in 2009 and generated considerable interest, probably because it gave JavaScript developers an opportunity to write server-side code even if they lacked a server-side background. It didn’t hurt that Chrome had established a reputation for being solid and fast, and Node used its V8 engine.

Today, it’s possible to run production servers on Node, and many people are doing so successfully. Taking it that far, however, is an investment. The Node project, and all the community-created modules that make it so awesome, is still a moving target. But even if you’re not ready to write and launch entire sites with Node, it’s plenty stable enough to use as a development tool.

It’s JavaScript, so if you can wire up a jQuery event handler, you can write a web server. It’s lightweight, so you can run it on your laptop and keep streaming music in the background. It’s dead simple to download, set up, and build in, so you don’t need the esoteric knowledge of an IT support person to get going with it. And the payoff is that instead of mockups and hard-coded data, you can design a set of client-side assets, page templates, and data schemas that are ready to launch to production.

Getting started

Installing Node locally for the most common environments is a piece of cake. You can download installers that include Node as well as npm, its package manager, from the project’s site. Installing it on a remote server is not quite that easy, but good documentation is available to help you out. After running through the installation process, you should be able to go to your terminal or command line and test it out.

If you don’t tell Node to run a specific file, you get a Read-Eval-Print Loop, or REPL. If you type node in your terminal or command prompt, you can begin to execute arbitrary JavaScript. For example, after starting the REPL, type var a = 9;. The REPL will respond with undefined. Now type a * 3 (or any other number) and it will respond with the correct result. You can make things more interesting by defining a function and then calling it:

> function sayHello( name ) { return “Hello, “ + name; }
> sayHello( “A List Apart” );
‘Hello, A List Apart’

To break out of the REPL, or end any other Node execution (like a running web server), press Ctrl+C. In the case of the REPL, you’ll need to press it twice to confirm.

While it’s nice to know Node can perform basic arithmetic and string concatenation, its value to us as developers is in running programs. You can see an example of one such program, a basic web server, on the project’s homepage. They suggest creating a file called example.js with this code:

var http = require(’http’);
http.createServer(function (req, res) {
  res.writeHead(200, {’Content-Type’: ‘text/plain’});
  res.end(’Hello World\n’);
}).listen(1337, ‘’);
console.log(’Server running at’);

This makes use of only one module, the core module http. As you can probably guess, the http module contains all the basic stuff you need to serve a site over HTTP. Node contains a tightly edited collection of core modules that provide things like event handlers, file system access, and abstractions for various network protocols. But just as you probably use a JavaScript library or framework to speed up and bulletproof development on the client side, for Node development beyond a simple "Hello World" you generally add other non-core modules using npm.

The http module does contain a createServer function, though, which is all you need to create a bare-bones web server. In the code above, once the server has been created, it listens to port 1337 on your local machine. When it receives a request, it sends back a text response.

One thing to note is that the work here is done in event handlers, as are most things in Node. The callback in createServer() handles a connection event, which occurs every time a new client contacts the server. To start this server, type node example.js in your terminal, and then open a browser to This triggers the connection event, and you should see the message in the callback.

To obtain any serious value from a Node server—even one not intended to ever go to production—it’s best to get familiar with the modules in npm. There are thousands available, but those you’d need to create a basic web application are some of the oldest and most stable, so don’t feel obligated to research them all before getting started. One that definitely comes in handy for designing an application is Express, an uncomplicated web application framework.

If you’re accustomed to installing open source projects by cloning a GitHub repository or downloading a zip file, you’ll probably enjoy npm. To install Express with npm, for example, go to your terminal or command line and type npm install express. As long as you’re online and have permission to write to your machine, this fetches all the code and assets Express needs to run, as well as any modules it has as dependencies. The first time you run npm from your working directory, all these elements will end up in a new node_modules subdirectory. Now the module is ready to be used in Node programs the same way we used http, via the require function.

Designing applications

The ideal use case for designing your application with Node is a single-page application in which the server mostly provides data, but Node is still useful for a more traditional site. Of course, you want to begin development with requirements defined as precisely as possible, but implementation tends to expose requirements you hadn’t considered, and some of those can have a considerable impact on your timeline. Even in a server-driven application where it may not be possible to reuse data structures and templates as-is, creating client-only versions helps test your assumptions about the data you need and how you’ll use it.

If you’re developing a single-page app, the justification is much easier. You’ll need to think about optimizing your communication with the server to require as few requests as possible, which means knowing how data should be packaged up by each server endpoint and how you’ll cache the data on receipt (if at all).

An advantage of having JavaScript on the server is that templates can be rendered by the same template engine on either the client or server side. This allows you to experiment on both sides and optimize for your situation. It’s also a timesaver to render the templates with JavaScript objects and consider only the way data must eventually be grouped (not how it’s stored in a database). Designing these groupings of data is the bulk of the work we can do with Node toward the end of what we traditionally consider application design.

Piecing together each page from disparate parts from all over the server is messy for an application in any language. Instead, whatever renders a page should have clear dependencies, and the result of each page or data request should combine those dependencies into a cohesive and sensibly organized unit.

If you’ve worked in a server-side framework in which a page or view is tied to a single object or model, and where additional data is imported and exposed in a different way, you probably understand how the alternative gets to be a nuisance. You’re probably also aware that the solution is a good view-model whose data is defined by each view, not the models that feed it. With this exercise, we aim to map out what goes in those view-models.

Using templates

There’s a strong likelihood that your production server does not run JavaScript, so you may end up converting templates you produce in this design phase. You could attempt to mitigate this by choosing a template engine like Mustache with existing parsers for a huge list of languages. Or you might choose one with minimal logic available (I find that the only things I want for a truly flexible template are conditionals, loops, and partials) and the option of changing the delimiters around the template tags to agree with your server template language. I’d argue that the process of getting all the data correctly placed in your HTML is a lot more difficult than doing a find and replace on the end result, so creating a template in JavaScript that you can use easily is time well spent even if it can’t be parsed by your production server.

You could choose to design the UI of your pages using hard-coded mockup data first and add the template tags afterward, or you could start with a template and some mockup data ready to go in your Node server. Even though it’s an extra step, I find the former easier, because the latter tends to require extra shifting of the mockup data. Starting with hard-coded data lets me examine the finished mockup and see what kinds of "objects" are present (e.g., a user, an item for sale, or a status update). That helps me create a flexible object hierarchy in my data more easily. But you may be naturally amazing at creating object hierarchies, so, by all means, do what you feel.

Wherever you begin, hammering out your templates should give you an indication of which parts of each page are dynamic and which data each requires. If subsections of your pages are rendered separately because they’re reused on different parent pages or because they’re also rendered by the client, converting your markup to templates also allows you to find the right balance between never repeating code and having absurdly tiny templates.

Real fake server interactions

If you’ve created high-fidelity wireframes that run in a browser, you know the annoyance of having only parts of a page be interactive, since every click means having to create a new view (even if you have a series of items that share the same behavior when clicked). You also know about copying and pasting the same data into multiple places, and updating each of them separately if the manner of presenting data should change. Designing your app with a server behind it removes those frustrations.

With the support of a server, it’s not a problem if the same data shows up in different displays all over the workflow you’re designing. Since the data lives on your Node server, you can write it once and reuse it as many ways as you like. You still have to consider how you’ll move it from server to client, though. When a user clicks on one of many items in a list, will she be taken to a new page, or will more data appear inline? Is the former the non-JavaScript fallback for the latter? Working that out for your app will tell you which endpoints the server needs, and which parameters need to be sent to it in query strings, form posts, or URLs. It’ll also help define the API for those requests, telling anyone who might work on your production server which keys you expect to correspond to which pieces of data.

Having a server to work with is especially nice if you’re in the business of making asynchronous requests. Obviously, you can get your mockup data, which is excellent, but you can also lazy-load assets like templates or stylesheets to consume that data. Testing the process of getting data and assets to the client validates your assumptions about not only the way you’re packaging them, but how you’re storing and structuring them. And, of course, it means a lot less wasted client-side JavaScript.

A mockup you can use

The end result of all this should be that you’ve moved all the mockup pieces out of your client-side JavaScript and HTML. You have a Node server that might not match your production framework, but does have clear definitions of everything the client side expects to exist—possibly even all viewable in a single file. You have templates and client-side requests that may require substitutions, but also separate your data from everything else and are at minimum easily convertible to whatever format is needed for production.

Could you do the same with any other server under the sun? Absolutely. But if you already know JavaScript and aren’t aiming to become a server-side developer, it makes sense to use the skills you already have. Node makes that pretty easy, while also letting you dig as deeply as you want into more complex servers, should your ambitions change. It’s simple to get going and flexible to extend, making Node an awesome tool for designing applications.

Ready to take your new Node skills for a spin? In “Node at Work: A Walkthrough,” I’ll take you through a live demo, and get specific about how to refine your own mockups.

13 Reader Comments

Load Comments