Skip to content

Quick Start

Overview

In this chapter, you'll create your first Node.js application and understand the basic concepts through hands-on examples. We'll build a simple web server and explore fundamental Node.js features.

Your First Node.js Application

Hello World Console Application

Create a file called hello.js:

javascript
// hello.js
console.log('Hello, Node.js!');
console.log('Current directory:', __dirname);
console.log('Current file:', __filename);
console.log('Node.js version:', process.version);

Run the application:

bash
node hello.js

Understanding Global Objects

Node.js provides several global objects:

javascript
// globals.js
console.log('=== Global Objects ===');
console.log('__dirname:', __dirname);
console.log('__filename:', __filename);
console.log('process.argv:', process.argv);
console.log('process.env.NODE_ENV:', process.env.NODE_ENV);

// Process information
console.log('\n=== Process Info ===');
console.log('Process ID:', process.pid);
console.log('Platform:', process.platform);
console.log('Architecture:', process.arch);
console.log('Memory usage:', process.memoryUsage());

Creating a Simple Web Server

Basic HTTP Server

javascript
// server.js
const http = require('http');

// Create server
const server = http.createServer((req, res) => {
  // Set response headers
  res.writeHead(200, { 'Content-Type': 'text/html' });
  
  // Send response
  res.end('<h1>Hello from Node.js Server!</h1>');
});

// Start server
const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`);
});

Run the server:

bash
node server.js

Visit http://localhost:3000 in your browser.

Enhanced Server with Routing

javascript
// enhanced-server.js
const http = require('http');
const url = require('url');

const server = http.createServer((req, res) => {
  const parsedUrl = url.parse(req.url, true);
  const path = parsedUrl.pathname;
  const method = req.method;

  // Set common headers
  res.setHeader('Content-Type', 'text/html');

  // Simple routing
  if (path === '/' && method === 'GET') {
    res.statusCode = 200;
    res.end(`
      <h1>Welcome to Node.js!</h1>
      <p>Try these routes:</p>
      <ul>
        <li><a href="/about">About</a></li>
        <li><a href="/api/users">API Users</a></li>
        <li><a href="/contact">Contact</a></li>
      </ul>
    `);
  } else if (path === '/about' && method === 'GET') {
    res.statusCode = 200;
    res.end('<h1>About Page</h1><p>This is a Node.js application!</p>');
  } else if (path === '/api/users' && method === 'GET') {
    res.setHeader('Content-Type', 'application/json');
    res.statusCode = 200;
    res.end(JSON.stringify({
      users: [
        { id: 1, name: 'John Doe', email: 'john@example.com' },
        { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
      ]
    }));
  } else if (path === '/contact' && method === 'GET') {
    res.statusCode = 200;
    res.end('<h1>Contact</h1><p>Email: contact@example.com</p>');
  } else {
    res.statusCode = 404;
    res.end('<h1>404 - Page Not Found</h1>');
  }
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Enhanced server running at http://localhost:${PORT}`);
});

Working with Modules

Creating Custom Modules

Create math-utils.js:

javascript
// math-utils.js
function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

function multiply(a, b) {
  return a * b;
}

function divide(a, b) {
  if (b === 0) {
    throw new Error('Division by zero is not allowed');
  }
  return a / b;
}

// Export functions
module.exports = {
  add,
  subtract,
  multiply,
  divide
};

Using the custom module:

javascript
// app.js
const mathUtils = require('./math-utils');

console.log('Addition:', mathUtils.add(5, 3));
console.log('Subtraction:', mathUtils.subtract(10, 4));
console.log('Multiplication:', mathUtils.multiply(6, 7));
console.log('Division:', mathUtils.divide(15, 3));

try {
  console.log('Division by zero:', mathUtils.divide(10, 0));
} catch (error) {
  console.error('Error:', error.message);
}

Using Built-in Modules

javascript
// built-in-modules.js
const fs = require('fs');
const path = require('path');
const os = require('os');

// File system operations
console.log('=== File System ===');
console.log('Current directory contents:');
fs.readdirSync('.').forEach(file => {
  console.log('-', file);
});

// Path operations
console.log('\n=== Path Operations ===');
console.log('Join paths:', path.join(__dirname, 'files', 'data.txt'));
console.log('File extension:', path.extname('app.js'));
console.log('Base name:', path.basename('/users/john/documents/file.txt'));

// Operating system info
console.log('\n=== OS Information ===');
console.log('Platform:', os.platform());
console.log('CPU architecture:', os.arch());
console.log('Total memory:', Math.round(os.totalmem() / 1024 / 1024), 'MB');
console.log('Free memory:', Math.round(os.freemem() / 1024 / 1024), 'MB');
console.log('Uptime:', Math.round(os.uptime() / 3600), 'hours');

Asynchronous Programming Basics

Callbacks

javascript
// callbacks.js
const fs = require('fs');

// Synchronous (blocking)
console.log('=== Synchronous File Reading ===');
try {
  const data = fs.readFileSync('package.json', 'utf8');
  console.log('File read successfully (sync)');
} catch (error) {
  console.error('Error reading file (sync):', error.message);
}

// Asynchronous (non-blocking)
console.log('\n=== Asynchronous File Reading ===');
fs.readFile('package.json', 'utf8', (error, data) => {
  if (error) {
    console.error('Error reading file (async):', error.message);
    return;
  }
  console.log('File read successfully (async)');
  console.log('File size:', data.length, 'characters');
});

console.log('This line executes immediately (async)');

Promises

javascript
// promises.js
const fs = require('fs').promises;

// Using Promises
console.log('=== Promise-based File Reading ===');

fs.readFile('package.json', 'utf8')
  .then(data => {
    console.log('File read successfully (promise)');
    return JSON.parse(data);
  })
  .then(packageInfo => {
    console.log('Package name:', packageInfo.name);
    console.log('Package version:', packageInfo.version);
  })
  .catch(error => {
    console.error('Error:', error.message);
  });

console.log('This line executes immediately (promise)');

Async/Await

javascript
// async-await.js
const fs = require('fs').promises;

async function readPackageInfo() {
  try {
    console.log('=== Async/Await File Reading ===');
    
    const data = await fs.readFile('package.json', 'utf8');
    console.log('File read successfully (async/await)');
    
    const packageInfo = JSON.parse(data);
    console.log('Package name:', packageInfo.name);
    console.log('Package version:', packageInfo.version);
    
    return packageInfo;
  } catch (error) {
    console.error('Error:', error.message);
    throw error;
  }
}

// Call async function
readPackageInfo()
  .then(info => {
    console.log('Processing complete');
  })
  .catch(error => {
    console.error('Failed to read package info');
  });

console.log('This line executes immediately (async/await)');

Building a Complete Example

Let's create a simple file-based note-taking application:

javascript
// notes-app.js
const fs = require('fs').promises;
const path = require('path');

class NotesApp {
  constructor() {
    this.notesFile = path.join(__dirname, 'notes.json');
  }

  async loadNotes() {
    try {
      const data = await fs.readFile(this.notesFile, 'utf8');
      return JSON.parse(data);
    } catch (error) {
      // File doesn't exist, return empty array
      return [];
    }
  }

  async saveNotes(notes) {
    await fs.writeFile(this.notesFile, JSON.stringify(notes, null, 2));
  }

  async addNote(title, content) {
    const notes = await this.loadNotes();
    const newNote = {
      id: Date.now(),
      title,
      content,
      createdAt: new Date().toISOString()
    };
    notes.push(newNote);
    await this.saveNotes(notes);
    return newNote;
  }

  async listNotes() {
    const notes = await this.loadNotes();
    return notes;
  }

  async deleteNote(id) {
    const notes = await this.loadNotes();
    const filteredNotes = notes.filter(note => note.id !== id);
    await this.saveNotes(filteredNotes);
    return filteredNotes.length < notes.length;
  }
}

// Usage example
async function main() {
  const app = new NotesApp();

  try {
    // Add some notes
    await app.addNote('First Note', 'This is my first note in Node.js!');
    await app.addNote('Learning Node.js', 'Node.js is awesome for server-side development.');

    // List all notes
    const notes = await app.listNotes();
    console.log('All Notes:');
    notes.forEach(note => {
      console.log(`- ${note.title} (ID: ${note.id})`);
      console.log(`  ${note.content}`);
      console.log(`  Created: ${note.createdAt}\n`);
    });

    console.log(`Total notes: ${notes.length}`);
  } catch (error) {
    console.error('Error:', error.message);
  }
}

// Run the application
main();

Command Line Arguments

javascript
// cli-app.js
const args = process.argv.slice(2);

if (args.length === 0) {
  console.log('Usage: node cli-app.js <command> [arguments]');
  console.log('Commands:');
  console.log('  greet <name>     - Greet someone');
  console.log('  calc <a> <b>     - Add two numbers');
  console.log('  info             - Show system info');
  process.exit(1);
}

const command = args[0];

switch (command) {
  case 'greet':
    const name = args[1] || 'World';
    console.log(`Hello, ${name}!`);
    break;

  case 'calc':
    const a = parseFloat(args[1]);
    const b = parseFloat(args[2]);
    if (isNaN(a) || isNaN(b)) {
      console.error('Please provide two valid numbers');
      process.exit(1);
    }
    console.log(`${a} + ${b} = ${a + b}`);
    break;

  case 'info':
    console.log('System Information:');
    console.log('- Node.js version:', process.version);
    console.log('- Platform:', process.platform);
    console.log('- Architecture:', process.arch);
    console.log('- Current directory:', process.cwd());
    break;

  default:
    console.error(`Unknown command: ${command}`);
    process.exit(1);
}

Test the CLI app:

bash
node cli-app.js greet John
node cli-app.js calc 15 25
node cli-app.js info

Best Practices Demonstrated

  1. Error Handling: Always handle errors in asynchronous operations
  2. Module Organization: Separate functionality into modules
  3. Async/Await: Use modern async patterns for cleaner code
  4. File Operations: Use promise-based file operations
  5. Command Line Interface: Handle command line arguments properly

Common Pitfalls to Avoid

  1. Blocking Operations: Don't use synchronous operations in production
  2. Unhandled Errors: Always handle promise rejections
  3. Global Variables: Avoid polluting the global namespace
  4. Hardcoded Values: Use environment variables for configuration

Next Steps

In the next chapter, we'll dive deeper into Node.js fundamentals and explore the core concepts that make Node.js powerful.

Practice Exercises

  1. Create a simple calculator CLI application
  2. Build a file organizer that sorts files by extension
  3. Create a basic HTTP server that serves static files
  4. Implement a simple logging system using file operations

Key Takeaways

  • Node.js applications start with a simple JavaScript file
  • Built-in modules provide powerful functionality
  • Asynchronous programming is essential in Node.js
  • Modules help organize code into reusable components
  • Error handling is crucial for robust applications
  • Command line arguments enable interactive applications

Content is for learning and research only.