Web Sites vs. Web Applications – What’s the Difference?

I’ve been a software developer for a while now and one of the types of software that I specialize in is web applications.

Now, I live in an area where technology is not a large segment of the local economy, so when I tell people that I meet that I build web applications, I often get the question…

“What’s the difference between a web site and a web application?”

First, Some History

To understand the relationship between these two concepts, we have to think back to 15-20 years ago. Back in the early days of the internet. Back then, the internet was still the world-wide-web made up of “sites”. To popular culture, everything on the internet was a “site”.

But one thing I’ve learned from studying pop culture (I studied film and video in college) is that once popular culture latches onto an idea, it takes a while to let go.

Fast-forward to now, the internet is full of new and innovative technology. And yet, if you wanted to know more about popular things on the internet, you would probably ask “What are some popular sites I should check out?” The term has largely stuck to mean “places”. So, in this context, we would believe that “site” is synonymous with “place”.

What Do You Need?

So, if site is synonymous with place, then why is it important to distinguish between a site and an application?

Well, with many things with technology, while this definition of “site” has stuck, internet technology has advanced far beyond this original definition. Sites are now vastly more complicated than 15 or 20 years ago. Sites exist on a spectrum of complexity ranging from relatively straightforward informational site to an interconnected series of applications like Facebook.

They also share different purposes and these purposes are what help a software developer determine where the effort used to create a site should be focused.

This becomes a problem when discussing what you need and how to “build a web site”. If we don’t share the same definition of “site”, then our conversations over how to build a your site are likely to be fraught with misunderstandings about what it actually takes. What do you need? How complex is it? Is it really a site or an application?

So, What’s the Difference?

If we go by “web sites” as defined by popular culture, then we have a problem when comparing “sites” to “applications”.

Is there a difference between a pitch and curveball?

See the problem? What we are comparing is a little bit of apples to Jonagolds. Using this definition of site, then a web application is a kind of web site. It becomes difficult to distinguish the differences between the two.

Instead, I propose that we can delineate between the two by describing the relationship that the site or application has with a visitor.

  • Web site: A place on the internet whose purpose to the visitor is to provide value through presentation of information. A site is largely a “one-way” relationship, where visitors consume content from the content creators.

  • Web application: A place on the internet that requires input from the user, aside from clicks, in order to provide substantial value to the user. An application is largely a “two-way” relationship, where visitors must interact either with each other or with the application or both.

Ok, we’ve defined the difference. But maybe the definition is still a little unclear. How about some examples?

But are there places that fall into both categories? Let’s look at the Waste Management site as an example. Could this qualify as both? It certainly could. Why?

  • The homepage definitely is a one-way relationship where Waste Management is providing the visitor information about their good and services.

  • However, you can see the visitor has the ability to pay their bill online. This would qualify as a web application, because the visitor will surely be required to provide some information to the bill pay application in order for it to be of any value.

What do we call this? A site? An application? In the case of Waste Management’s homepage, many technology professionals are starting to call this the “marketing site” in order to differentiate it from the online bill pay, which is considered an application. But of course, in order to provide a good visitor experience, they are all tied together.

So, you can see that even with these definitions, some sites may fall into both definitions, but that we can clearly define where a difference in behavior exists. My definitions are by no means meant to be dogma, but I hope they help the discussion of what it takes to build a web site or web application.

Testing That Elements Do Not Exist With Capybara

I came across a problem that I’ve had with Capybara testing that has come up for me before.

In my test, I needed to check that an element was not on screen. I was trying to use Capybara’s #find method combined with RSpec exist matchers to keep the tests fast.

admin_section = find("#admin")
expect(admin_section).not_to be_present

However, you can’t use Capybara’s #find method here in this case, because it will throw an error (ironically, that it can’t find the element, thus, returning nil) before the matcher can be evaluated. Capybara will also wait 2 seconds before finally throwing the error which will actually slow down the test.

I Googled for the answer and while this Stack Overflow answer does provide the basic answer, it doesn’t use the new “expect” syntax. Here is how to check that an element does not exist on-screen using the expect syntax.

expect(page).not_to have_selector("#admin")

I don’t test much for elements that are not on-screen. But, for certain, exceptional cases, I will test when I want to make sure that an element is not appearing on-screen (say, a link to the admin section when you are a typical user).

However, I rarely test solely that an element does not exist on screen. The reason for this is that there are too many ways that an element could not appear on-screen. For example, maybe normally a test needs to be logged-in for the scenario under test but for some reason, my tests are logging out early. Now, my “not present” test may still pass because the element still does not exist on-screen but that’s because I’m logged out.

To account for this, I usually include an assertion for a similar element nearby that should be visible and is related in behavior to the element that is supposed to be hidden.

expect(page).to have_selector("#profile-photo")
expect(page).not_to have_selector("#admin")

If you are curious, ThoughtBot’s Joe Ferris hits on the points about using RSpec matchers like “have_selector” over Capybara’s #find method in this post on asynchronous testing.

Setting Up Multiple Instances of MongoDB on OSX

This post was originally published in February 2013 on my old blog. Some of this information may no longer work. I am posting this just as a reference for those curious as to how I did this originally back in 2013. For more up-to-date information, I would check the MongoDB site or Google.

I ran into an interesting problem the other day. I was working on a problem that required MongoDB’s new aggregation framework that comes standard with MongoDB ~> 2.2. However, I already had a local version of MongoDB v2.0 installed on my mac via Homebrew which I was using to test and development a production database that we were running. Searching the web, I found very little information about how to setup multiple versions of MongoDB on the same local environment.

So, here are the steps I used for setting up a separate instance of MongoDB. Again, I had already installed MongoDB via Homebrew using brew install mongodb, so I’ll show you how to install your own version outside of homebrew.

First, you’ll need to download a version of MongoDB from their website. In this case, we’ll use the latest production release which is 2.2.2 at the time of this post. In addition, I will be using the 64-bit OSX version from their site.

Then create an empty directory wherever you would like MongoDB to live. I call it mongo2_2 here but you can call it whatever you would like:

mkdir mongo2_2

Then you need to untar the download into that directory. In this case it’s:

tar –zxvf ../mongodb-osx-x86_64-2.2.2.tgz

This should create a new directory mongodb-osx-x86_64-2.2.2. ‘cd’ into that directory and you will see that it has created a “bin” folder with all the MongoDB commands and executables. Some of these you may recognize, like the actual MongoDB process – mongod and the mongo shell, mongo.

Ok, you have mongo setup, but now you need a place to store the data. By default, mongod writes data to the /data/db/ directory.  However, if you have installed MongoDB via Homebrew, then mongo is configured to write to /usr/local/var/mongodb

For the ease of use, we’re just going to use the directory we are currently in. We’ll create a “data” directory in the current directory which should be something like:



mkdir data

Ok, now you should be all setup for a new instance of MongoDB. But first, before we fire that up, there are a couple of things to check first. If you installed MongoDB via Homebrew, then more than likely, MongoDB is running on startup. You can check if this just by running the mongo shell with the “mongo” command:


If an instance of mongod process is running, then it should have no problem connecting. It might give you a message like

MongoDB shell version: 2.0.x

Uh-oh, not what we wanted. This means that your other version of MongoDB is still running and you need to stop it before you can start up the new version. To double-check this run:

ps -ef | grep mongo

If mongo is running, you should see mongod in your list.

usr/local/bin/mongod run --config /usr/local/etc/mongod.conf

To triple-check this, MongoDB runs off port 27017 by default, you can go to localhost:27017 and you should see a message like this:

You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number

You can cancel a mongod process by running the mongo shell with the “mongo” command then issuing the following commands in the shell:

use admin 

You could try to just kill the mongod process in the terminal, but there are no guarantees about how that might affect your current MongoDB setup and database. I preferred the safe route this time.

Ok, now if you try to connect to MongoDB again using the mongo command. You should get an error:

Error: couldn't connect to server 

Good, now we know that process is gone. However, if you plan to use this setup more than once, I would recommend one more change. The homebrew version of MongoDB is still setup to start automatically on startup. To turn this off, you need to edit a LaunchAgent file that Homebrew sets up by default. First, cd into the LaunchAgent directory

cd ~/Library/LaunchAgents

You should see a file called homebrew.mxcl.mongodb.plist. Open up this file in your favorite file editing software and change the following line:




The next time you start up again, MongoDB will not start by default.

We just need to set the configurations for our new MongoDB instance and then we should be good to go. ‘cd’ back into the directory where you setup MongoDB.


In order to tell MongoDB your settings when you start a mongod process, you will need to setup a config file. Create a new mongod.conf in this directory and include the following code:

# Store data in ./my_data instead of the default /data/db
dbpath = ./data
port = 28028

# Only accept local connections
bind_ip = 

dbpath tells mongo where you data should be stored, in this case, the data directory we created earlier. Port sets the port where the mongod instance should run. You’ll have to set this to something other than the default 27017 or mongo will complain. Bind_ip is important and prevents outsiders from trying to connect to your db.

You can now start your new instance of mongodb. However, you can’t use the “mongod” command, this is pointing to the executable of your homebrew version. ‘cd’ into the mongodb-osx-x86_64-2.2.2 and run:

./bin/mongod --config mongod.conf

This will tell the terminal to look for the mongod executable in the current directory and to use your config file for setup. You should see a message like:

MongoDB starting : port=29029 dbpath=./data

Woo-hoo! Alright, now you can connect via the shell to make sure. Open a new terminal tab. You’ll need to run the “mongo” command from the ./bin directory like we did with mongod. You will also have to specify the port or the shell will try to connect to the default port and throw and an error. Run this command

./bin/mongo –port 28028

You should see something like this:

MongoDB shell version: 2.2.2
connecting to:

Success! Now you are free to play with a different version of MongoDB all you want without having to touch your current setup. When you are done, just remove the mongo2_2 directory and change the LaunchAgent back and you are all set!

Two Simple Steps Helped Me Learn Vim

I’ve wanted to learn Vim for a long time. But every time I tried to pick it up, I was overwhelmed with the endless possible keystrokes, perplexing modes, and odd navigation. I had been a Sublime Text 2 user for a long time (this is before 3). I ran through ‘vimtutor’ a couple of times, but even then, after I finished, I quickly forgot most of what I learned in the tutorial.

I knew that my lack of actually using it everyday was contributing to my slow progress. However, I was working for a consultancy and I needed to have a reasonable amount of efficiency in my daily programming, which I just didn’t have yet in Vim.

But, about six months ago, I decided to subscribe to Thoughtbot’s Learn program (now Upcase), and they had a series of videos all dedicated to learning Vim. The videos were very-well done and when I watched the videos, I saw how powerful Vim could be.

So, I decided to give it a shot again, but this time, I did two things differently, which dramatically helped my success.

#1 Use a Cheatsheet

This idea I think I got from Ben Orenstein (EDIT: Yep, found the article here and mentions the strategy below with the notecard) who mentioned using a cheatsheet. However, whenever I Googled “vim cheatsheet” I got images like this one…

vim cheatsheet

…which brought back nightmares of this…

periodic table

Those cheatsheets were overwhelming and lacking context, so they were of little help.

Another Strategy

I decided that every time I got stuck on how to do something in Vim, I would do a quick Google search to find out how to do it and then, keep track of those functions on a 3 x 5 notecard.

That’s right. An actual, physical, 3 x 5 notecard is my Vim cheatsheet. I keep it handy on my desk to reference it and add to it as I learn new things. Below is a photo of my current cheatsheet, because in reality, I’m believe I’m on iteration 3 of the cheatsheet. You could say I’m on version 0.3.

Adam DeLong Vim Cheatsheet

This was tremendously helpful, because early on, I often found myself trying to do the same things over and over in Vim and forgetting how they worked. Here’s a quick list of some of the things I would end up Googling…

Paste from the buffer in insert mode?
Comment out line in vim?
Indent a line in vim?
Copy two words in vim?

Of course, as I got better, I started to learn more “vim” efficient ways of doing things like the above. But writing down these steps helped me remember these individual steps.

#2 Complete Your Next Side Project in Vim

Like many curious developers, I often will have side projects that I work on during quiet nights and weekends. These projects are often done in technologies I’m already familiar with and don’t have the pressure of deadlines or hours to make which made them the perfect training ground to learn Vim.

So, after practicing and following along to the Vim videos, I decided to code my next project entirely in Vim. I will admit, I did not entirely adhere to this rule. I would sometimes get frustrated to the point where I would bust open ST2 in order to make a quick change that I had gotten stuck on. But for the most part, if I got stuck, I would Google, find the result and add it to my cheatsheet.

I noticed those times started to get less and less frequent. I started to feel really comfortable with the new Vim workflow. I decided to give it a try at work. I knew that at that point, if I ever got stuck, I could always Google and probably figure out the solution.

Sure enough, I started using Vim for work and before I knew it, it had been a week and I hadn’t opened ST2 once.

Additional Tips for Vim

While those steps were the most crucial to helping me learn Vim, here are a couple of additional tips.

  • Watch the talks on Vim from Ben Orenstein and Chris Hunt and learn from their dotfiles on github. Ben Orenstein and Chris Hunt
  • Use the ‘ctrlp’ plugin for file searching
  • ‘autoindent’ is your friend