What is Node.js? A beginner's introduction to JavaScript runtime
Tags: javascript, node, tutorial, beginners
Published: 2023-01-16 18:45:27

**Node.js** is an open-source, cross-platform, JavaScript runtime environment that executes JavaScript code outside of a web browser. Node.js is a popular, lightweight web framework for beginners, and it is used by many big companies like Netflix and Uber. 

When we typically think of JavaScript, our mind tends to go to web development. Until Node.js came along, there was really no way to run JavaScript outside of a browser. When we write a backend server and database, Node.js is a popular choice because we can run our code as a standalone application rather than something that can only be evaluated in a browser environment. 

Node.js is an important tool for any JavaScript developer to understand. So, today, we'll introduce you to Node.js and show you how to get started with a project. 

**Today, we will cover:**
* [What is Node.js?](#what-is)
* [Fundamentals of Node.js](#fundamentals)
* [Node.js Event Loop](#loop)
* [Get started with a project](#project)
* [What to learn next](#next)

![Node.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/olelkr8gxz7u6hqxbgl4.png)

<a name="what-is"></a>

## What is Node.js?

Node.js is an open-source, cross-platform JavaScript runtime environment used for executing JavaScript code outside of a web browser.

Node.js is a great web framework for beginners because it works great for **data-intensive applications**, like streaming and real-time apps, and Node.js makes it easy to start **building the back-end**.

Node.js allows us to **use JavaScript everywhere** and on any browser, including macOS, Linux, and Windows. When we say everywhere, we mean the front end, the middleware, and the back end. Node.js is, therefore, part of some very popular web development stacks, such as the MERN stack, MEVN stack, and MEAN stack. 

![JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tu8kkgzx89sh0w9ws6m2.png)

There are a number of characteristics that make Node.js what it is: 

* **Google Chrome V8 JavaScript Engine:** This runtime environment is built on the Google Chrome V8 JavaScript runtime engine. In the same way, a Java Virtual Machine translates bytecode, and the Chrome V8 JavaScript engine takes JavaScript and makes it readable.
* **Modules/Packages:** Node.js has npm, a node package manager, with a library of over 350,000 packages to help get your project or application off the ground with efficiency and ease. 
* **Event Driven, Single-Threaded I/O Model:**
JavaScript relies on user interactions or events to run. In most cases, code is run synchronously. Server requests and other such asynchronous tasks rely on a system of promises or async/await functions to handle these inputs and outputs. 

<br>

<a name="fundamentals"></a>

## Fundamentals of Node.js

Now that we know what Node.js is, let's explore the fundamentals of this tool.

<br>

### Console

The **console** is a module provided by Node.js that is akin to the JavaScript console in the browser when you inspect a webpage. The console has methods that are available for us to use for debugging purposes. 

* `console.log()`: Frequently used to log some sort of output. 
* `console.warn()`: Explicitly delivers a warning to the console.  
* `console.error()`: Explicitly delivers an error message to the console.  You can log an error as a string or as an object. If logged as a new `Error()`, a traceback will be included as part of the message. 
* `console.trace()`: Logs a traceback when an error occurs in your code. Gives the line number and column number of the file that the error probably occurred. 

<br>

### Buffer

At its core, the **Buffer class** in Node.js is a temporary storage solution for file systems. Due to its low-level nature, as web developers, we will rarely actually use the Buffer class directly. The main purpose of this class is to allocate memory. 

Let’s take a look below at a few methods that the Buffer class provides.

```js
const buf1 = Buffer.alloc(10);
console.log(buf1);

const buf2 = Buffer.alloc(5, 15);
console.log(buf2);

const buf3 = Buffer.allocUnsafe(10);
console.log(buf3);

buf3.fill(1);
console.log(buf3);

buf2.write("abcedf");
console.log(buf2);

const buf4 = Buffer.from([265, 6.5, -255, '7']);
console.log(buf4);

const buf5 = Buffer.from('Hello world');
console.log(buf5);

console.log(buf5.toString());
```

<br>

### File System

The **file system (fs) module** allows us to interact with files in Node.js. There are synchronous and asynchronous methods that can be used to read or write to a file using the fs module. In contrast to using the console or the Buffer class, we need to import the fs module into the file that we would like to use in order to get it to work. 

The code example below shows how the `readFile`, an asynchronous method, works. Notice that the last argument in the method is a callback function whose first argument is an error. By definition, this callback will always pass in the error first before the data. 

**Asynchronous Example:** 

The asynchronous nature of the `readFile` method doesn’t block other functions or lines of code from running. 

The synchronous method, `readFileSync`, however, blocks other lines of code from running until the file is finished reading. 

**Here’s an example:**

```js
const fs = require('fs')
 
fs.readFile('data.txt', 'utf-8', (err, data) => {
 if (err) {
   console.error(err)
   return
 }
 let array = data.split('\n')

 //props are id, first_name, last_name, email, gender and ip_address

 let mapped = array.map(person => {
   let new_person = person.split(',');
   return new Object({
     id: new_person[0],
     first_name: new_person[1],
     last_name: new_person[2],
     email: new_person[3],
     gender: new_person[4],
     ip: new_person[5]

   })
 });
  console.log(mapped)

});
 
console.log("Hit!")
```

**Synchronous Example:**

```js
const fs = require('fs')

try {
  const data = fs.readFileSync('data.txt', 'utf-8')
  let array = data.split('\n')

 //props are id, first_name, last_name, email, gender and ip_address

 let mapped = array.map(person => {
   let new_person = person.split(',');
   return new Object({
     id: new_person[0],
     first_name: new_person[1],
     last_name: new_person[2],
     email: new_person[3],
     gender: new_person[4],
     ip: new_person[5]

   })
 });
  console.log(mapped)

} catch (err) {
  console.error(err)
}

console.log("Hit!")
```

**data.txt:**

```
1,Annabell,Cicconetti,acicconetti0@example.com,Female,219.207.16.2
2,Silvana,Glasman,sglasman1@house.gov,Female,233.214.135.18
3,Rebeka,Redmile,rredmile2@utexas.edu,Female,121.106.165.14
4,Veriee,Jovis,vjovis3@japanpost.jp,Female,43.217.63.173
5,Melitta,Hanburry,mhanburry4@aboutads.info,Female,42.204.168.27
6,Alethea,Webben,awebben5@hatena.ne.jp,Female,189.126.43.49
7,Saxe,Leary,sleary6@behance.net,Male,95.156.25.21
8,Ario,Brabyn,abrabyn7@pcworld.com,Male,220.226.164.176
9,Marybeth,Ughelli,mughelli8@mit.edu,Female,251.234.218.207
10,Gothart,Tassell,gtassell9@freewebs.com,Male,247.146.121.230
11,Fairlie,Beevis,fbeevisa@stanford.edu,Male,161.219.190.148
12,Skippie,Station,sstationb@wikipedia.org,Male,178.184.167.113
13,Ashla,Tett,atettc@nature.com,Female,209.125.39.161
14,Belinda,Olin,bolind@discovery.com,Female,222.234.181.134
15,Laurianne,Ledgerton,lledgertone@google.co.uk,Female,184.56.226.2
16,Angele,Rhodus,arhodusf@ca.gov,Female,112.66.128.23
17,Meridith,Pena,mpenag@biblegateway.com,Female,163.227.38.120
18,Romola,Erbe,rerbeh@networksolutions.com,Female,184.50.183.25
19,Damien,Cominotti,dcominottii@naver.com,Male,122.62.139.51
20,Lou,Clemerson,lclemersonj@sfgate.com,Female,176.117.18.82
21,Donall,Lorence,dlorencek@shutterfly.com,Male,153.209.179.90
22,Maribeth,Sloam,msloaml@cbslocal.com,Female,177.119.164.156
23,Fowler,Pethybridge,fpethybridgem@vinaora.com,Male,58.228.162.249
24,Jarred,Haxley,jhaxleyn@ox.ac.uk,Male,26.74.46.200
25,Natalie,Outright,noutrighto@businessinsider.com,Female,181.218.16.217
26,Cloe,Devitt,cdevittp@gmpg.org,Female,109.68.184.211
27,Shane,Farmer,sfarmerq@ucsd.edu,Male,198.230.29.69
28,Iorgo,Thrower,ithrowerr@nsw.gov.au,Male,103.213.212.70
29,Letty,Dakhno,ldakhnos@pagesperso-orange.fr,Female,32.245.196.9
30,Woodrow,Flageul,wflageult@nsw.gov.au,Male,105.129.139.220
31,Franchot,Large,flargeu@statcounter.com,Male,219.98.60.51
32,Anna-diana,Callam,acallamv@51.la,Female,59.121.52.69
33,Benoit,Scallon,bscallonw@etsy.com,Male,227.53.63.103
34,Lavinie,Lovelady,lloveladyx@constantcontact.com,Female,227.20.131.192
35,Timoteo,Laurentino,tlaurentinoy@techcrunch.com,Male,149.251.44.30
36,Robers,Cassella,rcassellaz@google.pl,Male,179.219.60.199
37,Arnoldo,Eakly,aeakly10@live.com,Male,189.110.238.26
38,Janis,Didball,jdidball11@shinystat.com,Female,105.74.199.165
```

Try placing a `console.log(“Hit!”)` after the function to see when the console is actually logged. Is there a difference between the two functions? What is it? 

The `readFile` function will start the function and then immediately move to the rest of the code before the function completes and prints out the contents of our array. So, you should see something like this:

```js
Hit!
 
[
 {
   id: '1',
   first_name: 'Annabell',
   last_name: 'Cicconetti',
   email: 'acicconetti0@example.com',
   gender: 'Female',
   ip: '219.207.16.2'
 },
 etc…
]
```

In contrast, the `console.log(“Hit!”)` won’t run until after the `readFileSync` function is finished:

```js
[...{
   id: '37',
   first_name: 'Arnoldo',
   last_name: 'Eakly',
   email: 'aeakly10@live.com',
   gender: 'Male',
   ip: '189.110.238.26'
 },
 {
   id: '38',
   first_name: 'Janis',
   last_name: 'Didball',
   email: 'jdidball11@shinystat.com',
   gender: 'Female',
   ip: '105.74.199.165'
 }
]
Hit!
```

Writing to files is done in a very similar fashion, but the functions are called `writeFile()` and `writeFileSync()`.

<a name="loop"></a>

### Event Loop

Much of Node.js is built to be **event-driven**. When a user clicks on an interface or types in a form, an event is triggered to happen, and then something occurs as a result. To attach a function or set of functions to a specific event is emitting an event. 

These functions, called event listeners, are one part of an overall journey called the Event Loop. Take this example: 

```js

const EventEmitter = require('events');
 
const emitter = new EventEmitter();
 
const handleEvent = (str) => {
 console.log(`================ ${str}`);
 console.log("handleEvent fired! An event has happened!");
 console.log("end of event")
}
emitter.on('load event', () => handleEvent("load"));
emitter.on('hello event', () => handleEvent("hello"));
emitter.emit('load event');
emitter.emit('hello event')
```

In this code example, we are importing the events module. Next, we create a new `EventEmitter` and assign it to the variable emitter. In this particular example, we created a `handleEvent` function that will serve as a callback function that will console.log some things. 

The `EventEmitter` class has several methods we can use. One method that is run when an event is emitted is the `EventEmitter.on()` function. 

This particular method will fire when an event is emitted. The first argument passed into the function is the name of the event and the second is the callback function that tells us how to handle the event. 

In this particular example, there are two events being emitted. When we run the code above, we should get: 

```js

================ load
handleEvent fired! An event has happened!
end of event
================ hello
handleEvent fired! An event has happened!
end of event
true
```

The emit method triggers the on method which then invokes the `handleEvent` callback function. 

### Globals

Global objects are available in every module, so they can be used without importing a specific module. The `Buffer` class, for example, class is defined as a global in Node.js. Some other common global objects are: 
* The `console` object is used to print to `stdout` and `stderr`.
* Timers, such as `setImmediate`, `setInterval`, and `setTimeout`, are also globals.
* The `process` object is also global. 

> In a browser, the top-level scope is the global scope. But in Node.js, the top-level scope is not the global scope.

In Node.js, the global object can be used to see whatever is available in the **global scope**. Check out the code below to see an example. 

```js
console.log(global)
```

```js
//output:

Object [global] {
  global: [Circular],
  process:
   process {
     title: 'node',
     version: 'v10.17.0',
     versions:
      { http_parser: '2.8.0',
        node: '10.17.0',
        v8: '6.8.275.32-node.54',
        uv: '1.28.0',
        zlib: '1.2.11',
        brotli: '1.0.7',
        ares: '1.15.0',
        modules: '64',
        nghttp2: '1.39.2',
        napi: '5',
        openssl: '1.1.1d',
        icu: '64.2',
        unicode: '12.1',
        cldr: '35.1',
        tz: '2019a' },
     arch: 'x64',
     platform: 'linux',
     release:
      { name: 'node',
        lts: 'Dubnium',
        sourceUrl:
         'https://nodejs.org/download/release/v10.17.0/node-v10.17.0.tar.gz',
        headersUrl:
         'https://nodejs.org/download/release/v10.17.0/node-v10.17.0-headers.tar.gz' },
     argv: [ '/usr/local/bin/node', '/usercode/index.js' ],
     execArgv: [],
     env:
      { HOSTNAME: '52b6928cb0cb',
        HOME: '/root',
        OLDPWD: '/',
        PATH:
         '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
        LANG: 'C.UTF-8',
        NODE_PATH: '/usr/local/lib/node_modules/',
        PWD: '/usercode' },
     pid: 9,
     features:
      { debug: false,
        uv: true,
        ipv6: true,
        tls_alpn: true,
        tls_sni: true,
        tls_ocsp: true,
        tls: true },
     ppid: 8,
     execPath: '/usr/local/bin/node',
     debugPort: 9229,
     _debugProcess: [Function: _debugProcess],
     _debugEnd: [Function: _debugEnd],
     _startProfilerIdleNotifier: [Function: _startProfilerIdleNotifier],
     _stopProfilerIdleNotifier: [Function: _stopProfilerIdleNotifier],
     abort: [Function: abort],
     chdir: [Function: chdir],
     umask: [Function: umask],
     _getActiveRequests: [Function: _getActiveRequests],
     _getActiveHandles: [Function: _getActiveHandles],
     _kill: [Function: _kill],
     cwd: [Function: cwd],
     dlopen: [Function: dlopen],
     reallyExit: [Function: reallyExit],
     uptime: [Function: uptime],
     getuid: [Function: getuid],
     geteuid: [Function: geteuid],
     getgid: [Function: getgid],
     getegid: [Function: getegid],
     getgroups: [Function: getgroups],
     _rawDebug: [Function],
     moduleLoadList:
      [ 'Internal Binding module_wrap',
        'Binding contextify',
        'Internal Binding worker',
        'NativeModule events',
        'NativeModule internal/async_hooks',
        'NativeModule internal/errors',
        'Binding uv',
        'Binding buffer',
        'Binding async_wrap',
        'Internal Binding async_wrap',
        'Binding config',
        'Binding icu',
        'NativeModule util',
        'NativeModule internal/util/inspect',
        'Binding util',
        'NativeModule internal/util',
        'Binding constants',
        'Internal Binding types',
        'NativeModule internal/util/types',
        'NativeModule internal/validators',
        'NativeModule internal/encoding',
        'Internal Binding icu',
        'NativeModule buffer',
        'NativeModule internal/buffer',
        'NativeModule internal/process/per_thread',
        'NativeModule internal/process/main_thread_only',
        'NativeModule internal/process/stdio',
        'NativeModule assert',
        'NativeModule internal/assert',
        'NativeModule fs',
        'NativeModule path',
        'NativeModule internal/constants',
        'Binding fs',
        'NativeModule internal/fs/streams',
        'NativeModule internal/fs/utils',
        'NativeModule stream',
        'NativeModule internal/streams/pipeline',
        'NativeModule internal/streams/end-of-stream',
        'NativeModule internal/streams/legacy',
        'NativeModule _stream_readable',
        'NativeModule internal/streams/buffer_list',
        'NativeModule internal/streams/destroy',
        'NativeModule internal/streams/state',
        'NativeModule _stream_writable',
        'NativeModule _stream_duplex',
        'NativeModule _stream_transform',
        'NativeModule _stream_passthrough',
        'NativeModule internal/url',
        'NativeModule internal/querystring',
        'Binding url',
        'NativeModule internal/process/warning',
        'NativeModule internal/process/next_tick',
        'NativeModule internal/process/promises',
        'Internal Binding util',
        'NativeModule internal/fixed_queue',
        'Binding performance',
        'Binding trace_events',
        'NativeModule internal/inspector_async_hook',
        'Binding inspector',
        'NativeModule internal/options',
        'Internal Binding options',
        'NativeModule timers',
        'Binding timer_wrap',
        'NativeModule internal/linkedlist',
        'NativeModule internal/timers',
        'NativeModule console',
        'Binding tty_wrap',
        'Internal Binding tty_wrap',
        'NativeModule internal/fs/sync_write_stream',
        'NativeModule internal/modules/cjs/loader',
        'NativeModule vm',
        'NativeModule internal/modules/cjs/helpers',
        'NativeModule url',
        'NativeModule internal/safe_globals',
        'Internal Binding contextify' ],
     binding: [Function: binding],
     _linkedBinding: [Function: _linkedBinding],
     _events:
      [Object: null prototype] {
        newListener: [Function],
        removeListener: [Function],
        warning: [Function] },
     _eventsCount: 3,
     _maxListeners: undefined,
     _fatalException: [Function],
     domain: null,
     _exiting: false,
     assert: [Function: deprecated],
     config: { target_defaults: [Object], variables: [Object] },
     setUncaughtExceptionCaptureCallback: [Function],
     hasUncaughtExceptionCaptureCallback: [Function],
     emitWarning: [Function],
     nextTick: [Function: nextTick],
     _tickCallback: [Function: _tickCallback],
     stdout: [Getter],
     stderr: [Getter],
     stdin: [Getter],
     openStdin: [Function],
     initgroups: [Function: initgroups],
     setegid: [Function: setegid],
     seteuid: [Function: seteuid],
     setgid: [Function: setgid],
     setuid: [Function: setuid],
     setgroups: [Function: setgroups],
     hrtime: { [Function: hrtime] bigint: [Function] },
     cpuUsage: [Function: cpuUsage],
     memoryUsage: [Function: memoryUsage],
     exit: [Function],
     kill: [Function],
     argv0: 'node',
     allowedNodeEnvironmentFlags: [Getter/Setter],
     mainModule:
      Module {
        id: '.',
        exports: {},
        parent: null,
        filename: '/usercode/index.js',
        loaded: false,
        children: [],
        paths: [Array] } },
  Buffer:
   { [Function: Buffer]
     poolSize: 8192,
     from: [Function: from],
     of: [Function: of],
     alloc: [Function: alloc],
     allocUnsafe: [Function: allocUnsafe],
     allocUnsafeSlow: [Function: allocUnsafeSlow],
     isBuffer: [Function: isBuffer],
     compare: [Function: compare],
     isEncoding: [Function: isEncoding],
     concat: [Function: concat],
     byteLength: [Function: byteLength],
     [Symbol(kIsEncodingSymbol)]: [Function: isEncoding] },
  clearImmediate: [Function: clearImmediate],
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setImmediate:
   { [Function: setImmediate] [Symbol(util.promisify.custom)]: [Function] },
  setInterval: [Function: setInterval],
  setTimeout:
   { [Function: setTimeout] [Symbol(util.promisify.custom)]: [Function] } }
```

<br>

<a name="project"></a>

## How to build a basic Node.js project

Let's learn how to get started with Node.js by creating a simply Node.js file. In this example, we will be setting up our computer to work as a server! 

> If you would like to learn how to create a Node.js app, check out this [beginner course from Educative](https://www.educative.io/courses/learn-nodejs-complete-course-for-beginners?eid=5082902844932096).

<br>

### Install Node.js and NPM

First, you need to Go to the site [Node.js site](https://nodejs.org/en/download/) and download the files. 

Follow the installation prompts and restart your machine for the best results.  

> Another way you can install Node.js is to use a package manager.

Then, test that it's working by printing the version using the following command:

```js
> node -v
```

You should also test npm by printing the version using the following command:

```js
> npm -v
```

### Create a file 

Once you have installed Node.js properly, create a Node.js file. In this example, we have named it named "first.js". We then add the following code and save the file on your computer like so: `C:\Users\Your Name\first.js`


```js
var http = require('http');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end('Hello World!');
}).listen(8080);
```

This code is essentially telling the computer to print "Hello World!" when accessed on port 8080.

<br>

### Command-line interface

Node.js files must be initiated in your computer's "Command Line Interface" program. Navigate to the folder that contains the file "first.js".

```js
C:\Users\Your Name>_
```

<br>

### Initiate your file 

This file needs to then be initiated by Node.js. Do this by starting your command line interface, writing `node first.js`, and clicking enter:

```js
C:\Users\Your Name>node myfirst.js
```

Awesome! Now your computer is set up as a server, so when you access the computer on port 8080, the"Hello World!" message will print.

To see this in real time, open your browser, and type: `http://localhost:8080`

<a name="next"></a>

## What to learn next

Congrats! You know the basics of Node.js, its fundamental tools, and how to start a Node.js file. The next steps are to master Node.js modules, the HTTP Modules, the File system, and NPM dependencies. 

A good next step would be to learn the following concepts of Node.js:
* Node.js and OS
* Node.js REPL
* Packages
* How to publish a package
* How to build a functioning app
* Node.js and MySQL

To get started with these advanced topics, check out Educative's course **[Learn Node.js: The Complete Course for Beginners](https://www.educative.io/courses/learn-nodejs-complete-course-for-beginners?eid=5082902844932096)**, which covers all these topics and more in detail. You'll explore advanced concepts like modules, events, and packages. At the end of this course, you will get hands-on with Node.js and create your own food delivery web application.

*Happy learning!*

### Continue reading about Node.js and JavaScript on Educative
* [Node.js vs React.js: which to choose for your web app project](https://www.educative.io/blog/nodejs-vs-reactjs?eid=5082902844932096) 
* [Best practices for securing your Node.js apps](https://www.educative.io/blog/secure-nodejs-apps-best-practices?eid=5082902844932096)
* [Learn JavaScript OOP: A primer for web development](https://www.educative.io/blog/javascript-oop-primer?eid=5082902844932096)

### Start a discussion
What is your favorite use of node.js in the professional world? Was this article helpful? Let us know in the comments below!