Learning Server-Side JavaScript with Node.js
Tutorial Details
- Technology: JavaScript
- Difficulty: Intermediate-Advanced
Node.js is all the buzz at the moment, and makes creating high performance, real-time web applications easy. It allows JavaScript to be used end to end, both on the server and on the client. This tutorial will walk you through the installation of Node and your first “Hello World” program, to building a scalable streaming Twitter server.
What is Node.js?
JavaScript has traditionally only run in the web browser, but recently there has been considerable interest in bringing it to the server side as well, thanks to the CommonJS project. Other server-side JavaScript environments include Jaxer and Narwhal. However, Node.js is a bit different from these solutions, because it is event-based rather than thread based. Web servers like Apache that are used to serve PHP and other CGI scripts are thread based because they spawn a system thread for every incoming request. While this is fine for many applications, the thread based model does not scale well with many long-lived connections like you would need in order to serve real-time applications like Friendfeed or Google Wave.
“Every I/O operation in Node.js is asynchronous…”
Node.js, uses an event loop instead of threads, and is able to scale to millions of concurrent connections. It takes advantage of the fact that servers spend most of their time waiting for I/O operations, like reading a file from a hard drive, accessing an external web service or waiting for a file to finish being uploaded, because these operations are much slower than in memory operations. Every I/O operation in Node.js is asynchronous, meaning that the server can continue to process incoming requests while the I/O operation is taking place. JavaScript is extremely well suited to event-based programming because it has anonymous functions and closures which make defining inline callbacks a cinch, and JavaScript developers already know how to program in this way. This event-based model makes Node.js very fast, and makes scaling real-time applications very easy.
Step 1 Installation
Node.js runs on Unix based systems, such as Mac OS X, Linux, and FreeBSD. Unfortunately, Windows is not yet supported, so if you are a Windows user, you can install it on Ubuntu Linux using Virtualbox. To do so, follow this tutorial. You will need to use the terminal to install and run Node.js.
- Download the latest release of Node.js from nodejs.org (the latest version at the time of this writing is 0.1.31) and unzip it.
- Open the terminal, and run the following commands.
cd /path/to/nodejs make sudo make install
A lot of messages will be outputted to the terminal as Node.js is compiled and installed.

Step 2 Hello World!
Every new technology starts with a “Hello World!” tutorial, so we will create a simple HTTP server that serves up that message. First, however, you have to understand the Node.js module system. In Node, functionality is encapsulated in modules which must be loaded in order to be used. There are many modules listed in the Node.js documentation. You load these modules by using the require function like so:
var sys = require("sys");
This loads the sys module, which contains functions for dealing with system level tasks like printing output to the terminal. To use a function in a module, you call it on the variable that you stored the module in, in our case sys.
sys.puts("Hello World!");
Running these two lines is as simple as running the node command with the filename of the javascript file as an argument.
node test.js
This will output “Hello World!” to the command line when run.

To create an HTTP server, you must require the http module.
var sys = require("sys"),
http = require("http");
http.createServer(function(request, response) {
response.sendHeader(200, {"Content-Type": "text/html"});
response.write("Hello World!");
response.close();
}).listen(8080);
sys.puts("Server running at http://localhost:8080/");
This script imports the sys and http modules, and creates an HTTP server. The anonymous function that is passed into http.createServer will be called whenever a request comes in to the server. Once the server is created, it is told to listen on port 8080. When a request to the server comes in, we first send HTTP headers with the content type and status code of 200 (successful). Then we send “Hello World!” and close the connection. You might notice that we have to explicitly close the connection. This will make it very easy to stream data to the client without closing the connection. If you run this script and go to http://localhost:8080/ in your browser, you will see “Hello World!”

Step 3 A Simple Static File Server
OK, so we have built an HTTP server, but it doesn’t send anything except for “Hello World,” no matter what URL you go to. Any HTTP server must be able to send static files such as HTML files, images and other files. The following code does just that:
var sys = require("sys"),
http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs");
http.createServer(function(request, response) {
var uri = url.parse(request.url).pathname;
var filename = path.join(process.cwd(), uri);
path.exists(filename, function(exists) {
if(!exists) {
response.sendHeader(404, {"Content-Type": "text/plain"});
response.write("404 Not Found\n");
response.close();
return;
}
fs.readFile(filename, "binary", function(err, file) {
if(err) {
response.sendHeader(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.close();
return;
}
response.sendHeader(200);
response.write(file, "binary");
response.close();
});
});
}).listen(8080);
sys.puts("Server running at http://localhost:8080/");
We start by requiring all of the modules that we will need in our code. This includes the sys, http, url, path, and fs or filesystem modules. Next we create an HTTP server like we did before. This time, we will use the url module to parse the incoming URL of the request and find the pathname of the file being accessed. We find the actual filename on the server’s hard drive by using path.join, which joins process.cwd(), or the current working directory, with the path to the file being requested. Next, we check if the file exists, which is an asynchronous operation and thus requires a callback. If the file does not exist, a 404 Not Found message is sent to the user and the function returns. Otherwise, we read the file using the fs module using the “binary” encoding, and send the file to the user. If there is an error reading the file, we present the error message to the user, and close the connection. Because all of this is asynchronous, the server is able to serve other requests while reading the file from the disk no matter how large it is.
If you run this example, and navigate to http://localhost:8080/path/to/file, that file will be shown in your browser.

Step 4 A Real Time Tweet Streamer
Building on our static file server, we will build a server in Node.js that streams tweets to a client that is served through our static file server. To start, we will need one extra module in this example: the events module. Node has a concept called an EventEmitter, which is used all over to handle event listeners for asynchronous tasks. Much like in jQuery or another client side JavaScript framework where you bind event listeners to things like mouse clicks, and AJAX requests, Node allows you to bind event listeners to many things, some of which we have already used. These include every I/O operation, such as reading a file, writing a file, checking if a file exists, waiting for HTTP requests, etc. The EventEmitter abstracts the logic of binding, unbinding, and triggering such event listeners. We will be using an EventEmitter to notify listeners when new tweets are loaded. The first few lines of our tweet streamer imports all of the required modules, and defines a function for handling static files, which was taken from our previous example.
var sys = require("sys"),
http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs"),
events = require("events");
function load_static_file(uri, response) {
var filename = path.join(process.cwd(), uri);
path.exists(filename, function(exists) {
if(!exists) {
response.sendHeader(404, {"Content-Type": "text/plain"});
response.write("404 Not Found\n");
response.close();
return;
}
fs.readFile(filename, "binary", function(err, file) {
if(err) {
response.sendHeader(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.close();
return;
}
response.sendHeader(200);
response.write(file, "binary");
response.close();
});
});
}
We have used the http module to create a server before, but it is also possible to create an HTTP client using the module. We will be creating an HTTP client to load tweets from Twitter’s public timeline, which is performed by the get_tweets function.
var twitter_client = http.createClient(80, "api.twitter.com");
var tweet_emitter = new events.EventEmitter();
function get_tweets() {
var request = twitter_client.request("GET", "/1/statuses/public_timeline.json", {"host": "api.twitter.com"});
request.addListener("response", function(response) {
var body = "";
response.addListener("data", function(data) {
body += data;
});
response.addListener("end", function() {
var tweets = JSON.parse(body);
if(tweets.length > 0) {
tweet_emitter.emit("tweets", tweets);
}
});
});
request.close();
}
setInterval(get_tweets, 5000);
First, we create an HTTP client on port 80 to api.twitter.com, and create a new EventEmitter. The get_tweets function creates an HTTP “GET” request to Twitter’s public timeline, and adds an event listener that will be triggered when Twitter’s servers respond. Because Node.js is asynchronous, the data in the body of the response comes in chunks, which are picked up by the response’s “data” listener. This listener simply appends the chunk to the body variable. Once all of the chunks have come in, the “end” listener is triggered, and we parse the incoming JSON data. If more than one tweet is returned, we emit the “tweets” event on our tweet_emitter, and pass in the array of new tweets. This will trigger all of the event listeners listening for the “tweets” event, and send the new tweets to each client. We retreive the new tweets every five seconds, by using setInterval.
Finally, we need to create the HTTP server to handle requests.
http.createServer(function(request, response) {
var uri = url.parse(request.url).pathname;
if(uri === "/stream") {
var listener = tweet_emitter.addListener("tweets", function(tweets) {
response.sendHeader(200, { "Content-Type" : "text/plain" });
response.write(JSON.stringify(tweets));
response.close();
clearTimeout(timeout);
});
var timeout = setTimeout(function() {
response.sendHeader(200, { "Content-Type" : "text/plain" });
response.write(JSON.stringify([]));
response.close();
tweet_emitter.removeListener(listener);
}, 10000);
}
else {
load_static_file(uri, response);
}
}).listen(8080);
sys.puts("Server running at http://localhost:8080/");
Just as we did with our static file server, we create an HTTP server that listens on port 8080. We parse the requested URL, and if the URL is equal to "/stream", we will handle it, otherwise we pass the request off to our static file server. Streaming consists of creating a listener to listen for new tweets on our tweet_emitter, which will be triggered by our get_tweets function. We also create a timer to kill requests tht last over 10 seconds by sending them an empty array. When new tweets come in, we send the tweets as JSON data, and clear the timer. You will see how this works better after seeing the client side code, which is below. Save it as test.html in the same directory as the server side JavaScript.
<!DOCTYPE html>
<html>
<head>
<title>Tweet Streamer</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
</head>
<body>
<ul id="tweets"></ul>
<script type="text/javascript">
var tweet_list = $("#tweets");
function load_tweets() {
$.getJSON("/stream", function(tweets) {
$.each(tweets, function() {
$("<li>").html(this.text).prependTo(tweet_list);
});
load_tweets();
});
}
setTimeout(load_tweets, 1000);
</script>
</body>
</html>
Here, we have a simple HTML page that imports the jQuery library and defines an unordered list to put the tweets in. Our client side JavaScript caches the tweet list, and runs the load_tweets function after one second. This gives the browser enough time to finish loading the page before we start the AJAX request to the server. The load_tweets function is very simple: It uses jQuery’s getJSON function to load /stream. When a response comes in, we loop through all of the tweets and prepend them to the tweet list. Then, we call load_tweets again. This effectively creates a loop that loads new tweets, which times out after ten seconds because of the timeout on the server. Whenever there are new tweets, they are pushed to the client which maintains a continuous connection to the server. This technique is called long-polling.
If you run the server using node and go to http://localhost:8080/test.html, you will see the Twitter public timeline stream into your browser.

Next Steps
Node.js is a very exciting technology that makes it easy to create high performance real time applications. I hope you can see its benefit, and can use it in some of your own applications. Because of Node’s great module system, it is easy to use prewritten code in your application, and there are many third party modules available for just about everything – including database connection layers, templating engines, mail clients, and even entire frameworks connecting all of these things together. You can see a complete list of modules on the Node.js wiki, and more Node tutorials can be found on How To Node. I would also recommend that you watch a video from JSConf, in which Ryan Dahl, the creator of Node, describes the design philosophy behind Node. That is available here.
I hope you have enjoyed this tutorial. If you have any comments, you can leave one here or send me a message on Twitter. Happy noding!









jQuery Lightbox Evolution only $12.00
Events Calendar Pro - Wordpr ... only $30.00 
Awesome!!!! this is exactly what I need!!!!!
Thank You, Thank You, Thank You!!1
very interesting, I’ve seen Jaxer before back when I used Aptana as my IDE. But I steared clear because I was under the impression that it was a closed source project and I need to host with Aptana (the company). This looks worth a try, though it may be a weird feeling writing javascript on the server side.
Thanks
I agree that it sucks you have to use aptana’s server for jaxer (which isn’t true but it’s extreamly complicated otherwise) but it’s a much better implementation since you don’t have to make your own http server and it lets you access the DOM.
Wow! This is really cool! I will try this out!
1.How do we use this on a pre-existing server?
2.The live Preview doesn’t work. I presume that’s because the Netttuts server doesn’t have Node.js?
Nice tut.
Hey Rohan,
Pretty much doesn’t work on most Shared hosting plans I’d guess. I am not being paid by these people, nor do I have any financial association with them, but WebFaction (google em) does a really nice job of giving their users full shell access. I was able to upload Node.js, unzip it, and even compile it on their server (dayum). Then I had to create a reference in their control panel to point a subdomain to my Node.JS instance. After that was done, I started up a Node.JS server and opened up the subdomain in my browser.
Pain in the ass? Well, sorta. Works on most shared plans? No. Real problems, such as if it crashes, it’s not a daemon that can be auto-restarted? Yes. Works for testing and to push this technology further: DEFINITELY!!! Go have fun!
Hey Devon,
Thanks for taking the time to put this tutorial together. A few quick questions/comments:
If there are no threads, and it is completely asynchronous, then how do you prevent race conditions? There was a note in the documentation under standard I/0 stating that even when you pipe to files, there is no blocking. What happens when two different “event streams” pipe to the same file?
Also, I did not see any benchmarks against a similar threaded application with concurrent users. Is this something that nodejs provides somewhere? Whenever there is talk of performance, I want to see it with my own eyes.
I would also be careful when discussing the terms asynchronous, thread and concurrency. The reality is that a single core can really only handle one thread at a time. On that single core there are amazingly complex algorithms that determine what thread to run, and when to run it. Per nodejs.org, the current implementation does not use more than one core… I find it difficult to imagine that an enterprise application running on a single core with nodejs would be faster than a multi-threaded application running on several server cores.
With that being said, this is still a great tutorial. You did a nice job introducing the concepts and presenting the opportunities.
The V8 JS engine uses only one core, however the thread pool is used to make synchronous I/O asynchronous – using pipes to communicate to the V8 main application thread, utilizing other cores.
Since main application logic is handled by callbacks – there are no race conditions as such, however if callback takes too long to process the other pending events will be delayed – so event handlers that require long processing time should offload this task to another child process (either another node instance or other standalone executable), that will most likely run concurrently on another core.
Am I missing something or is the demo page not working?
Demo isn’t working. :\
This is because the servers that Nettuts is hosting the demo on do not have Node.js installed.
Wow server side JavaScript that is so cool! Great tutorial!
Awesome! I’m going to start programming in JS now
I tried setting this up on my Ubuntu machine but it won’t work. I get these error messages:
root@myserver:/home/www/node.js# node test.js
Server running at http://127.0.0.1:8000/
TypeError: Object # has no method ‘writeHead’
at Server. (/home/anton/www/node.js/test.js:4:12)
at EventEmitter. (/usr/local/lib/node/libraries/http.js:411:23)
at ServerSideConnection. (/usr/local/lib/node/libraries/http.js:332:12)
at node.js:1027:9
at node.js:1031:1
Are you running the newest version of Node? Older versions had a different API.
I get the same error in a similar Ubuntu setup. Running the latest stable version 0.1.26.
I tried compiling the latest version (v0.1.32-22-g217e4b4) and that seems to work just fine. At least the Hello World web server example works. Maybe that will work for you too, Anton?
@Devon, do me a favour, can you check once which version you were on trying this thing out? i need to try it out. i am getting all sorts of has “no methods errors.. ”
thanks for the share. great post.
I believe the older API used writeHead(), the newer one uses write()… Try switching that out.
Thanks for tutorial.
But this is far future before it really will be used and as i see it now it would benefit in large scale projects only.
THIS is one of that tutorials i wait for. High class, well explained and simple but really usefull realworld example.
I’m impressed.
Brilliant tutorial, this kind of article makes me watching tutsplus feed every day. However there is a bug in your code…
From specification: “emitter.removeListener(event, listener)” and you pass to removeListener an instance of EventEmiter, not a listener, using “tweet_emitter.removeAllListeners(‘tweets’);” will solve the crashing problem (it occurs when the server times out)
Magnificent !! Really.
Excellent tutorial for learning server side java script .
Great article! I’m going to have to look into server side js more. One of the most informative tutorials I’ve seen on nettuts. Keep great things like this article coming.
Cool technology and great tutorial !
But that means you have to know c++ to extend it, and it’s fairly complicated to compile it.
Its really great for online games, or realtime applications. Now couple this with xmlsocket in Flash and you have a cool online game !!!
Dude, that’s exactly what I was thinking.
When this becomes available on bought servers, there’s your game-server framework right there.
Beats paying through the teeth for smartfoxserver
That was one nice server side language, now if only it ran on windows boxes I’d be very glad (running virtual machines, setting them up and figuring out what’s wrong with them is a pain).
does anybody know if there’s a windows release planned ?? if so please respond, thank you
It could be really, really useful if Node.js worked with some highly available database, such as CouchDB. Anybody knows how to do it?
Take a look at some of the database connection libraries for Node on this page – http://wiki.github.com/ry/node/modules#database
Very interesting indeed. I’d just written a crappy Node.js server, but it wasn’t written quite as nice as yours! Always fun to see different examples of the same code. Great tut!
Check out http://github.com/sixtus/node-couch for a node.js CouchDB implementation.
This looks like it could be the Next Big Thing ™ for this year
That is an excellent example and demonstration of using JavaScript in a new manner.
Is it just me or does the demo not do anything. Tried chrome and firefox.
The demo link above does not work because Nettuts does not have the Node.js server installed and thus only the client is running with no server to talk to. You will have to follow the tutorial to see the result.
Will definitely use this in my next project!
Not trying to comment spam, but I thought I’d tell people interested in learning more about these two great links:
http://howtonode.org/ – Awesome Node.JS Tutorials
http://github.com/visionmedia/express – Express Node Web Framework (Like Ruby’s Sinatra for Node.JS).
First is a great resource, second a fun project to play with!
Happy hacking, errbody!
This looks nice! (Yet) another thing to put on my « You have to know this » list! You know, that constantly growing list…
By the way, you’re missing a letter in the word “that” (“tht”) in this sentence :
“…a timer to kill requests tht last over 10 seconds…”
Great tutorial.
If anyone is interested in statically typed node.js, have a look at my haxe (www.haxe.org) bindings for node.js here http://www.github.com/blackdog66/hxNode, as an example,
import js.Node;
class Main {
public static function
main() {
var
sys:Sys = Node.require(“sys”),
http:Http = Node.require(“http”),
google = http.createClient(80, “www.google.cl”),
request = google.request(“GET”,”/”, {host: “www.google.cl”});
request.addListener(‘response’,function (response) {
sys.puts(“STATUS: ” + response.statusCode);
sys.puts(“HEADERS: ” + Node.stringify(response.headers));
response.setBodyEncoding(“utf8″);
response.addListener(“data”, function (chunk) {
sys.puts(“BODY: ” + chunk);
});
});
request.close();
}
}
what’s the difference? It’s haxe syntax which is compile time checked to javascript like this …
haxe -cp . -D nodejs -js main.js Main
and executed with
node main.js
Is it possible to run, just for testing purposes, node.js on an ubuntu live CD?
Wonderful tutorial. Thanks for sharing!
is it similar to “comet” style server (either apache mods or dedicated software such as APE – http://www.ape-project.org/ or nginx http push module) ?
you have to run
./configure
first when installing nodejs.
It seems every time I open the Twitter Feed page firbug is throwing me an error on the second “GET” operation.
“a is null” jquery.min.js line 29.
I’ve pretty copied over all my code with the code from the tutorial and its still not giving way. Not sure what the deal is.
Fixed that last problem, everything seems to be running ok. Still no tweets though.
Can someone explain when this is needed to be used,why should i makes JS a server-side language?
Well put tutorial, I’m a sucker for helloWorld introductions as they ease you in a new concept or language. Was intersetd about this since I heard of it at the jQuery conf in San Francisco. Gotta get my hands dirty now.
This makes me feel funny in my pants.
pfff this tutorial is so great! i love it
Hello net.tutsplus.com folks
Vacation is here, I’m bored. Came to discover some extra entertaining jokes.
Show me your suggestions ^_^
Browsing on Google for something else closely connected, regardless before i ramble on too much i would just like to state how much I cherished your post, I’ve added your web blog and also obtained your Feed, Again thank you very much for the article carry on the good work.
Great tutorial.. Node.js is so exciting. JavaScript is a functional language and for those of us who cherish functional languages like Erlang, or Clojure but not able to necessarily find jobs using them, JavaScript on the server side is the next best thing. JavaScript core is beautiful despite its mistakes as stated by the Master himself, and I am so happy I can use it on the server side thanks to node.js (event base definitely trumps the others based on threads.)
Keep these coming. And the commentators, thanks for the links.
Great post.
I was able to get my node.js server running and if I navigate to the URL in the browser I can get “hello world” to appear.
My question is how can I get that information to show up on another page(via ajax call, web sockets)?
Anyone’s help would be greatly appreciated!
Thanks,
Dan
I was able to get my node.js server running and if I navigate to the URL in the browser I can get “hello world” to appear.
My question is how can I get that information to show up on another page(via ajax call, web sockets)?
Anyone’s help would be greatly appreciated!
Thanks,
Dan
Thanks a lot, great tutorial! Really makes getting started easy.
Thank you!! Thank you!! Thank you!!
Great tutorial managed to follow and get most of the stuff to work apart from the twitter part,
Anyway i think the static file server was working as i was able to view the node.js readme file in my browser but now i am having trouble getting that to work so i must of broken something but don’t know how to re-install node.js i tried compiling and then running make install but hasn’t fixed it so is there a way to remove node.js so i can install again.
And then this might be the daftest question but where do i put file to server using the static file server example? as i fear the readme file i managed to view was just a fluke as no other file seem to work even they where in the same place (the unzipped node.js folder)
Thanks
So, I noticed that you’re pulling tweets from twitter every 5 seconds (api limitations). Why use node in this case rather than a standard ajax call every 5 seconds?
What is the benefit? I understand the benefit in the sense of chat or real time mapping web activity (i.e. following a user around your site (creepy) or tracking where users are hitting you from…etc) but when it comes to polling data at an interval, I’m not convinced node (or any COMET style solution) is beneficial.
Writing AJAX posts at that same interval that either pull back data or nothing seems to me to be just as efficient.
Thoughts?
The benefits of long polling (for which NodeJS is a great fit) is that you don’t poll needlessly in the event that the data you are polling for doesn’t update. If the data only changed once a minute and your short-polling solution polled every 5 seconds, you would be making 12 requests per minute. With a long-polling timeout of 10 seconds (which polls internally every 5 seconds), you would only be making 6 requests per minute, while still fetching data from Twitter every 5 seconds. The difference is which machine does the 5 second fetching – client (short-polling) or server (long-polling). Increasing the long-poll timeout even further has obvious benefits…Adding in web sockets (for the browsers that support them) also has obvious benefits…
for those of you interested in benchmarking stats:
Platform: Ubuntu 10.04 (Virtual Box)
Processor: AMD Turion 2.3GHz
Processing: Sleep for 1 second and output simple string
NodeJS:
oncurrency Level: 150
Time taken for tests: 30.042 seconds
Complete requests: 4266
Failed requests: 0
Write errors: 0
Total transferred: 324216 bytes
HTML transferred: 51192 bytes
Requests per second: 142.00 [#/sec] (mean)
Time per request: 1056.323 [ms] (mean)
Time per request: 7.042 [ms] (mean, across all concurrent requests)
Transfer rate: 10.54 [Kbytes/sec] received
Concurrency Level: 250
Time taken for tests: 30.035 seconds
Complete requests: 6795
Failed requests: 0
Write errors: 0
Total transferred: 516496 bytes
HTML transferred: 81552 bytes
Requests per second: 226.24 [#/sec] (mean)
Time per request: 1105.044 [ms] (mean)
Time per request: 4.420 [ms] (mean, across all concurrent requests)
Transfer rate: 16.79 [Kbytes/sec] received
Apache2/PHP5:
Concurrency Level: 150
Time taken for tests: 30.316 seconds
Complete requests: 3573
Failed requests: 0
Write errors: 0
Total transferred: 800576 bytes
HTML transferred: 42888 bytes
Requests per second: 117.86 [#/sec] (mean)
Time per request: 1272.732 [ms] (mean)
Time per request: 8.485 [ms] (mean, across all concurrent requests)
Transfer rate: 25.79 [Kbytes/sec] received
Concurrency Level: 250
Time taken for tests: 30.020 seconds
Complete requests: 3428
Failed requests: 0
Write errors: 0
Total transferred: 768096 bytes
HTML transferred: 41148 bytes
Requests per second: 114.19 [#/sec] (mean)
Time per request: 2189.337 [ms] (mean)
Time per request: 8.757 [ms] (mean, across all concurrent requests)
Transfer rate: 24.99 [Kbytes/sec] received
The more concurrent connections, the more NodeJS flies compared to Apache2/PHP5.
One remark about the structure of your tutorial : I really did not get at first why I should add a server for static files to the twitter polling part. I erased all code bits related to static files and decided to open the file directly in my browser (using the file menu), but this will not work since my browser will not accept to load data from a server (in this case : localhost:8080) which is different from the base document (for which, the “server” was my file system). Maybe you should talk a bit about this constraint, since it makes clearer the reason to use your static file server.
Another small issue : the allowed rate for request to the twitter api is currently of 1500 req/hour. So, the current code is broken, since it makes too much requests.