How to setup a Node.js server on Mac OS X in less than 10 minutes

Updated:2/27/2017.

Anyone who has spent any time developing enterprise Java applications knows what a time-consuming process it is just to create and configure an application server.  So when something comes along that makes creating a server fast and simple you got to fall in love with it.   Node.js with Express does that.  If you’re unfamiliar with Node.js or Express, the previous links will give you an overview of the products.  To better understand the backing behind the Node movement, here’s a short list of websites that currently use it.  Impressive.

Ready to get started?  Here’s how to set up your first server in a few simple steps:

  1. Change the ownership of your /usr/local directory to avoid any issues with Brew later. Open a command window and type the following command.  It will then prompt you for your Mac password.
    $ sudo chown -R $USER /usr/local
  2. Next ensure you have Xcode installed and it is updated to the latest version. Go to the Apple menu and select “Software Update…”. Update Xcode if needed.
  3. Install the Xcode command line utilities if you haven’t already.  Open a terminal window and type:
    $ xcode-select --install
  4. We’ll use Brew to install Node.  Depending on your version of Mac OS, Brew might already be installed.  Let’s make sure it is installed and up to date. In the terminal window type:
    $ brew update
  5. If you don’t have Brew installed, install it using this command:
    $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  6. Follow the directions on screen if you run into errors with XCode licensing.
    $ brew update
    ==> Migrating Homebrew to v0.9.9
    Error: You have not agreed to the Xcode license. Please resolve this by running:
      sudo xcodebuild -license
  7. Now let’s use Brew Doctor to ensure the system is in good shape.  In the terminal window type:
    $ brew doctor
  8. You should see a list of any outdated libraries or other warnings.  You may need to install or update xQuartz as Brew will hate you if you don’t. You can choose to fix any other reported issues now or do it later.
    Please note that these warnings are just used to help the Homebrew maintainers
    with debugging if you file an issue. If everything you use Homebrew for is
    working fine: please don't worry and just ignore them. Thanks!
    
    Warning: Your XQuartz (2.7.5) is outdated.
    Please install XQuartz 2.7.9 (or delete the current version).
    XQuartz can be updated using Homebrew-Cask by running
      brew cask reinstall xquartz
    
    Warning: You have MacPorts or Fink installed:
      /Users/Rick/.rvm/bin/port, /opt/local/bin/port
    
    This can cause trouble. You don't have to uninstall them, but you 
    may want to temporarily move them out of the way, e.g.
      sudo mv /opt/local ~/macports
    
    Warning: Broken symlinks were found. Remove them with `brew prune`:
      /usr/local/etc/bash_completion.d/brew_bash_completion.sh
      /usr/local/opt/bash-completion
      /usr/local/opt/python3
      /usr/local/opt/rabbitmq
      /usr/local/opt/ssh-copy-id
      /usr/local/opt/wget
  9. Now let’s finally install Node.js and npm.  In that same terminal window, type:
    $ brew install node
  10. Both node and npm should now be installed. Check this by typing the following in the terminal:
    $ node -v
     v0.10.33
    $ npm -v
     2.1.11
  11. Now add the following paths to your environment.  Type the following in the terminal:
  12. $ export NODE_PATH="/usr/local/lib/node"
    $ export PATH="/usr/local/share/npm/bin:$PATH"
  13. So far so good?  Good, let’s install Express now.  In the terminal, type:
    $ npm install -g express-generator
  14. Great!  So at this point Node, npm, and Express should all be installed.  Let’s create your first app.  First create a directory for your app in your home directory:
    $ cd ~
    $ mkdir myApp
  15. Now let’s use Express to generate the framework for the app.  In the terminal, type:
    $ express --css stylus myApp
  16. Now build myApp by using npm to install all the dependencies.  In the terminal type:
    $ cd myApp 
    $ npm install
  17. Express will generate several folders and files within your myApp folder.  You can use npm to verify this:
    $ npm ls
    myapp@0.0.0 /Users/Rick/dev/myApp
    ├─┬ body-parser@1.16.1
    │ ├── bytes@2.4.0
    │ ├── content-type@1.0.2
    │ ├── depd@1.1.0
    │ ├─┬ http-errors@1.5.1
    │ │ ├── inherits@2.0.3
    │ │ ├── setprototypeof@1.0.2
    │ │ └── statuses@1.3.1
    │ ├── iconv-lite@0.4.15
    │ ├─┬ on-finished@2.3.0
    │ │ └── ee-first@1.1.1
    │ ├── qs@6.2.1
    │ ├─┬ raw-body@2.2.0
    │ │ └── unpipe@1.0.0
    │ └─┬ type-is@1.6.14
      ├── media-typer@0.3.0
      └─┬ mime-types@2.1.14
        └── mime-db@1.26.0
    ├─┬ cookie-parser@1.4.3
    │ ├── cookie@0.3.1
    │ └── cookie-signature@1.0.6
    ├─┬ debug@2.6.1
    │ └── ms@0.7.2
    ├─┬ express@4.14.1
    │ ├─┬ accepts@1.3.3
    │ │ ├─┬ mime-types@2.1.14
    │ │ │ └── mime-db@1.26.0
    │ │ └── negotiator@0.6.1
    │ ├── array-flatten@1.1.1
    │ ├── content-disposition@0.5.2
    │ ├── content-type@1.0.2
    │ ├── cookie@0.3.1
    │ ├── cookie-signature@1.0.6
    │ ├─┬ debug@2.2.0
    │ │ └── ms@0.7.1
    │ ├── depd@1.1.0
    │ ├── encodeurl@1.0.1
    │ ├── escape-html@1.0.3
    │ ├── etag@1.7.0
    │ ├─┬ finalhandler@0.5.1
    │ │ ├── statuses@1.3.1
    │ │ └── unpipe@1.0.0
    │ ├── fresh@0.3.0
    │ ├── merge-descriptors@1.0.1
    │ ├── methods@1.1.2
    │ ├─┬ on-finished@2.3.0
    │ │ └── ee-first@1.1.1
    │ ├── parseurl@1.3.1
    │ ├── path-to-regexp@0.1.7
    │ ├─┬ proxy-addr@1.1.3
    │ │ ├── forwarded@0.1.0
    │ │ └── ipaddr.js@1.2.0
    │ ├── qs@6.2.0
    │ ├── range-parser@1.2.0
    │ ├─┬ send@0.14.2
    │ │ ├── destroy@1.0.4
    │ │ ├─┬ http-errors@1.5.1
    │ │ │ ├── inherits@2.0.3
    │ │ │ └── setprototypeof@1.0.2
    │ │ ├── mime@1.3.4
    │ │ ├── ms@0.7.2
    │ │ └── statuses@1.3.1
    │ ├── serve-static@1.11.2
    │ ├─┬ type-is@1.6.14
    │ │ ├── media-typer@0.3.0
    │ │ └─┬ mime-types@2.1.14
    │ │   └── mime-db@1.26.0
    │ ├── utils-merge@1.0.0
    │ └── vary@1.1.0
    ├─┬ jade@1.11.0
    │ ├── character-parser@1.2.1
    │ ├─┬ clean-css@3.4.25
    │ │ ├─┬ commander@2.8.1
    │ │ │ └── graceful-readlink@1.0.1
    │ │ └─┬ source-map@0.4.4
    │ │   └── amdefine@1.0.1
    │ ├── commander@2.6.0
    │ ├─┬ constantinople@3.0.2
    │ │ └── acorn@2.7.0
    │ ├─┬ jstransformer@0.0.2
    │ │ ├── is-promise@2.1.0
    │ │ └─┬ promise@6.1.0
    │ │   └── asap@1.0.0
    │ ├─┬ mkdirp@0.5.1
    │ │ └── minimist@0.0.8
    │ ├─┬ transformers@2.1.0
    │ │ ├─┬ css@1.0.8
    │ │ │ ├── css-parse@1.0.4
    │ │ │ └── css-stringify@1.0.5
    │ │ ├─┬ promise@2.0.0
    │ │ │ └── is-promise@1.0.1
    │ │ └─┬ uglify-js@2.2.5
    │ │   ├─┬ optimist@0.3.7
    │ │   │ └── wordwrap@0.0.3
    │ │   └─┬ source-map@0.1.43
    │ │     └── amdefine@1.0.1
    │ ├─┬ uglify-js@2.7.5
    │ │ ├── async@0.2.10
    │ │ ├── source-map@0.5.6
    │ │ ├── uglify-to-browserify@1.0.2
    │ │ └─┬ yargs@3.10.0
    │ │   ├── camelcase@1.2.1
    │ │   ├─┬ cliui@2.1.0
    │ │   │ ├─┬ center-align@0.1.3
    │ │   │ │ ├─┬ align-text@0.1.4
    │ │   │ │ │ ├─┬ kind-of@3.1.0
    │ │   │ │ │ │ └── is-buffer@1.1.4
    │ │   │ │ │ ├── longest@1.0.1
    │ │   │ │ │ └── repeat-string@1.6.1
    │ │   │ │ └── lazy-cache@1.0.4
    │ │   │ ├─┬ right-align@0.1.3
    │ │   │ │ └─┬ align-text@0.1.4
    │ │   │ │   ├─┬ kind-of@3.1.0
    │ │   │ │   │ └── is-buffer@1.1.4
    │ │   │ │   ├── longest@1.0.1
    │ │   │ │   └── repeat-string@1.6.1
    │ │   │ └── wordwrap@0.0.2
    │ │   ├── decamelize@1.2.0
    │ │   └── window-size@0.1.0
    │ ├── void-elements@2.0.1
    │ └─┬ with@4.0.3
      ├── acorn@1.2.2
      └─┬ acorn-globals@1.0.9
        └── acorn@2.7.0
    ├─┬ morgan@1.7.0
    │ ├── basic-auth@1.0.4
    │ ├─┬ debug@2.2.0
    │ │ └── ms@0.7.1
    │ ├── depd@1.1.0
    │ ├─┬ on-finished@2.3.0
    │ │ └── ee-first@1.1.1
    │ └── on-headers@1.0.1
    ├─┬ serve-favicon@2.3.2
    │ ├── etag@1.7.0
    │ ├── fresh@0.3.0
    │ ├── ms@0.7.2
    │ └── parseurl@1.3.1
    └─┬ stylus@0.54.5
      ├── css-parse@1.7.0
      ├─┬ glob@7.0.6
      │ ├── fs.realpath@1.0.0
      │ ├─┬ inflight@1.0.6
      │ │ └── wrappy@1.0.2
      │ ├── inherits@2.0.3
      │ ├─┬ minimatch@3.0.3
      │ │ └─┬ brace-expansion@1.1.6
      │ │   ├── balanced-match@0.4.2
      │ │   └── concat-map@0.0.1
      │ ├─┬ once@1.4.0
      │ │ └── wrappy@1.0.2
      │ └── path-is-absolute@1.0.1
      ├─┬ mkdirp@0.5.1
      │ └── minimist@0.0.8
      ├── sax@0.5.8
      └─┬ source-map@0.1.43
        └── amdefine@1.0.1
  18. All that is left now is to start the server.  In the terminal type:
    $ npm start
    > myapp@0.0.0 start /Users/Rick/dev/myApp
    > node ./bin/www
  19. Open a browser and enter the url: localhost:3000.  Voila!
    express
Advertisements

9 comments

  1. This worked GREAT! My only issue (but I’m picky) was a warning that followed after running “brew doctor” stating that “/usr/local/lib isn’t writable” I found this article on stack overflow: http://stackoverflow.com/questions/14527521/brew-doctor-says-warning-usr-local-include-isnt-writable/34405333#34405333

    By following the stack overflow advice I used “sudo chown -R JonJames:admin /usr/local/lib” to fix the problem- running “brew doctor” again returned “Your system is ready to brew.”

    The syntax to fix your “brew doctor” Warnings may be different in term of the path you use: I used “lib” at the end of my path, others have used things like “bin” or “include” in the path to fix the issue, the Warning it prints in the terminal should explain to you which path is not writable, however the syntax that Homebrew suggests in the Warning seems to be off, it will require a “:” to run correctly, if it does run correctly it should prompt you for your system admin password within the terminal before performing the chown operation..

  2. Tutorials like this are very unclear. I folloed every step as described. At th end I use http://localhost:3000 an get this “Safari cannot connect to the server” Throught other forumes i found out
    it should be :
    npm install -g express-generator
    brfore
    npm install -g express

    And the url for this link
    ruby <(curl -fsSkL raw.github.com/mxcl/homebrew/go)
    yeild to an error
    curl: (22) The requested URL returned error: 400 Bad Request

    Also npm ls:
    look nothing like the "Author" said and yeild a bunch of missing dependencies:
    npm ERR! missing: body-parser@~1.16.0, required by myapp@0.0.0
    npm ERR! missing: cookie-parser@~1.4.3, required by myapp@0.0.0
    npm ERR! missing: debug@~2.6.0, required by myapp@0.0.0
    npm ERR! missing: express@~4.14.1, required by myapp@0.0.0
    npm ERR! missing: jade@~1.11.0, required by myapp@0.0.0
    npm ERR! missing: morgan@~1.7.0, required by myapp@0.0.0
    npm ERR! missing: serve-favicon@~2.3.2, required by myapp@0.0.0

    If the author doesn't know what he's talking about, DON'T write an artical like this, it serves no purpose but to obfuscate newbiees like me as well as many others!

    1. Welcome to the wonderful and often frustrating world of ever-changing tech. This tutorial was originally written way back in 2013. Much has changed since then and updates to commands were provided in the comments section. I’m glad you were able to get it working. -RC

  3. Worked my way through and enjoyed the successful Mucho Gusto .. Bueno Dias.. LOL
    Thanks bunches .. UDEMY was going to bilk me for $20 to do what you provided..
    Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s