Skip to main content

Node.js First Application - Building Your First Node.js App

In this chapter, we'll create your first Node.js applications, starting with simple console applications and progressing to web servers. You'll learn the fundamental concepts and see Node.js in action.

Prerequisites

Before starting, ensure you have:

  • Node.js installed (version 14 or higher recommended)
  • A text editor or IDE
  • Basic knowledge of JavaScript

Application 1: Simple Console Application

Let's start with the classic "Hello World" program.

Step 1: Create the Application

Create a new file called hello.js:

// hello.js
console.log("Hello, World!");
console.log("Welcome to Node.js!");
console.log("Current time:", new Date().toLocaleString());

Step 2: Run the Application

Open your terminal and navigate to the directory containing hello.js:

node hello.js

Output:

Hello, World!
Welcome to Node.js!
Current time: 12/25/2024, 10:30:45 AM

Step 3: Understanding the Code

  • console.log(): Outputs text to the console
  • new Date(): Creates a new Date object
  • .toLocaleString(): Formats the date for the current locale

Application 2: Interactive Console Application

Let's create a more interactive application that accepts user input.

Step 1: Create the Application

Create a file called interactive.js:

// interactive.js
const readline = require('readline');

// Create readline interface
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

// Ask for user's name
rl.question('What is your name? ', (name) => {
console.log(`Hello, ${name}!`);
console.log(`Welcome to Node.js, ${name}!`);

// Ask for user's age
rl.question('How old are you? ', (age) => {
console.log(`You are ${age} years old.`);
console.log(`You were born in ${new Date().getFullYear() - age}.`);

// Close the readline interface
rl.close();
});
});

// Handle close event
rl.on('close', () => {
console.log('Goodbye!');
process.exit(0);
});

Step 2: Run the Application

node interactive.js

Sample Output:

What is your name? John
Hello, John!
Welcome to Node.js, John!
How old are you? 25
You are 25 years old.
You were born in 1999.
Goodbye!

Step 3: Understanding the Code

  • readline: Built-in Node.js module for reading user input
  • createInterface(): Creates a readline interface
  • question(): Prompts the user with a question
  • process.stdin: Standard input stream
  • process.stdout: Standard output stream

Application 3: File Operations Application

Let's create an application that reads and writes files.

Step 1: Create the Application

Create a file called file-operations.js:

// file-operations.js
const fs = require('fs');
const path = require('path');

// Create a sample text file
const fileName = 'sample.txt';
const content = `Hello from Node.js!
This is a sample file created by our first application.
Current timestamp: ${new Date().toISOString()}
Node.js version: ${process.version}
Platform: ${process.platform}`;

// Write file
fs.writeFile(fileName, content, (err) => {
if (err) {
console.error('Error writing file:', err);
return;
}
console.log('File written successfully!');

// Read the file back
fs.readFile(fileName, 'utf8', (err, data) => {
if (err) {
console.error('Error reading file:', err);
return;
}
console.log('\nFile content:');
console.log('='.repeat(40));
console.log(data);
console.log('='.repeat(40));

// Get file information
fs.stat(fileName, (err, stats) => {
if (err) {
console.error('Error getting file stats:', err);
return;
}
console.log('\nFile information:');
console.log(`Size: ${stats.size} bytes`);
console.log(`Created: ${stats.birthtime}`);
console.log(`Modified: ${stats.mtime}`);
});
});
});

Step 2: Run the Application

node file-operations.js

Output:

File written successfully!

File content:
========================================
Hello from Node.js!
This is a sample file created by our first application.
Current timestamp: 2024-12-25T10:30:45.123Z
Node.js version: v18.17.0
Platform: linux
========================================

File information:
Size: 156 bytes
Created: Wed Dec 25 2024 10:30:45 GMT+0000 (UTC)
Modified: Wed Dec 25 2024 10:30:45 GMT+0000 (UTC)

Step 3: Understanding the Code

  • fs: File system module for file operations
  • writeFile(): Asynchronously writes data to a file
  • readFile(): Asynchronously reads file contents
  • stat(): Gets file statistics
  • path: Module for working with file paths

Application 4: Simple Web Server

Now let's create a basic HTTP web server.

Step 1: Create the Application

Create a file called web-server.js:

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

// Create HTTP server
const server = http.createServer((req, res) => {
// Parse the URL
const parsedUrl = url.parse(req.url, true);
const path = parsedUrl.pathname;
const query = parsedUrl.query;

// Set content type
res.setHeader('Content-Type', 'text/html; charset=utf-8');

// Handle different routes
if (path === '/') {
res.writeHead(200);
res.end(`
<html>
<head>
<title>My First Node.js Server</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.container { max-width: 600px; margin: 0 auto; }
.header { color: #333; border-bottom: 2px solid #007acc; }
.info { background: #f5f5f5; padding: 20px; border-radius: 5px; }
</style>
</head>
<body>
<div class="container">
<h1 class="header">Welcome to My First Node.js Server!</h1>
<div class="info">
<h2>Server Information</h2>
<p><strong>Node.js Version:</strong> ${process.version}</p>
<p><strong>Platform:</strong> ${process.platform}</p>
<p><strong>Architecture:</strong> ${process.arch}</p>
<p><strong>Uptime:</strong> ${Math.floor(process.uptime())} seconds</p>
<p><strong>Current Time:</strong> ${new Date().toLocaleString()}</p>
</div>
<h2>Available Routes</h2>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/api/info">API Info</a></li>
<li><a href="/hello?name=YourName">Hello with Query</a></li>
</ul>
</div>
</body>
</html>
`);
} else if (path === '/about') {
res.writeHead(200);
res.end(`
<html>
<head><title>About</title></head>
<body>
<h1>About This Server</h1>
<p>This is a simple Node.js web server created as a first application.</p>
<p><a href="/">← Back to Home</a></p>
</body>
</html>
`);
} else if (path === '/api/info') {
res.setHeader('Content-Type', 'application/json');
res.writeHead(200);
res.end(JSON.stringify({
message: 'Hello from Node.js API!',
timestamp: new Date().toISOString(),
nodeVersion: process.version,
platform: process.platform,
uptime: process.uptime()
}, null, 2));
} else if (path === '/hello') {
const name = query.name || 'World';
res.writeHead(200);
res.end(`
<html>
<head><title>Hello ${name}</title></head>
<body>
<h1>Hello, ${name}!</h1>
<p>Welcome to Node.js!</p>
<p><a href="/">← Back to Home</a></p>
</body>
</html>
`);
} else {
res.writeHead(404);
res.end(`
<html>
<head><title>404 Not Found</title></head>
<body>
<h1>404 - Page Not Found</h1>
<p>The requested page "${path}" was not found.</p>
<p><a href="/">← Back to Home</a></p>
</body>
</html>
`);
}
});

// Start the server
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}/`);
console.log('Press Ctrl+C to stop the server');
});

// Handle server errors
server.on('error', (err) => {
console.error('Server error:', err);
});

// Graceful shutdown
process.on('SIGINT', () => {
console.log('\nShutting down server...');
server.close(() => {
console.log('Server closed');
process.exit(0);
});
});

Step 2: Run the Application

node web-server.js

Output:

Server running at http://localhost:3000/
Press Ctrl+C to stop the server

Step 3: Test the Application

Open your web browser and visit:

  • http://localhost:3000/ - Home page
  • http://localhost:3000/about - About page
  • http://localhost:3000/api/info - JSON API endpoint
  • http://localhost:3000/hello?name=John - Hello page with query parameter

Step 4: Understanding the Code

  • http: Built-in module for creating HTTP servers
  • url: Module for parsing URLs
  • createServer(): Creates an HTTP server
  • listen(): Starts the server on a specific port
  • writeHead(): Sets response headers
  • end(): Sends response and closes connection

Application 5: Command Line Calculator

Let's create a simple command-line calculator.

Step 1: Create the Application

Create a file called calculator.js:

// calculator.js
const readline = require('readline');

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

function calculate(num1, operator, num2) {
const a = parseFloat(num1);
const b = parseFloat(num2);

switch (operator) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b === 0) {
throw new Error('Division by zero is not allowed');
}
return a / b;
case '%':
return a % b;
case '**':
return a ** b;
default:
throw new Error('Invalid operator');
}
}

function askQuestion() {
rl.question('Enter calculation (e.g., 5 + 3) or "quit" to exit: ', (input) => {
if (input.toLowerCase() === 'quit') {
console.log('Goodbye!');
rl.close();
return;
}

const parts = input.trim().split(' ');
if (parts.length !== 3) {
console.log('Invalid format. Please use: number operator number');
askQuestion();
return;
}

try {
const result = calculate(parts[0], parts[1], parts[2]);
console.log(`${input} = ${result}`);
} catch (error) {
console.log(`Error: ${error.message}`);
}

askQuestion();
});
}

console.log('Welcome to Node.js Calculator!');
console.log('Supported operators: +, -, *, /, %, **');
console.log('Type "quit" to exit\n');

askQuestion();

Step 2: Run the Application

node calculator.js

Sample Output:

Welcome to Node.js Calculator!
Supported operators: +, -, *, /, %, **
Type "quit" to exit

Enter calculation (e.g., 5 + 3) or "quit" to exit: 10 + 5
10 + 5 = 15
Enter calculation (e.g., 5 + 3) or "quit" to exit: 20 / 4
20 / 4 = 5
Enter calculation (e.g., 5 + 3) or "quit" to exit: 2 ** 8
2 ** 8 = 256
Enter calculation (e.g., 5 + 3) or "quit" to exit: quit
Goodbye!

Application 6: File System Explorer

Let's create a simple file system explorer.

Step 1: Create the Application

Create a file called file-explorer.js:

// file-explorer.js
const fs = require('fs');
const path = require('path');
const readline = require('readline');

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

function listDirectory(dirPath) {
try {
const items = fs.readdirSync(dirPath);
const stats = items.map(item => {
const itemPath = path.join(dirPath, item);
const stat = fs.statSync(itemPath);
return {
name: item,
isDirectory: stat.isDirectory(),
size: stat.size,
modified: stat.mtime
};
});

// Sort: directories first, then files
stats.sort((a, b) => {
if (a.isDirectory && !b.isDirectory) return -1;
if (!a.isDirectory && b.isDirectory) return 1;
return a.name.localeCompare(b.name);
});

console.log(`\nContents of: ${dirPath}`);
console.log('='.repeat(50));
console.log('Type'.padEnd(10) + 'Size'.padEnd(12) + 'Modified'.padEnd(20) + 'Name');
console.log('-'.repeat(50));

stats.forEach(item => {
const type = item.isDirectory ? 'DIR' : 'FILE';
const size = item.isDirectory ? '-' : formatBytes(item.size);
const modified = item.modified.toLocaleDateString();
console.log(type.padEnd(10) + size.padEnd(12) + modified.padEnd(20) + item.name);
});

console.log('-'.repeat(50));
console.log(`Total: ${stats.length} items`);

} catch (error) {
console.log(`Error reading directory: ${error.message}`);
}
}

function formatBytes(bytes) {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
}

function askCommand(currentPath) {
rl.question(`\n[${currentPath}]> `, (input) => {
const parts = input.trim().split(' ');
const command = parts[0].toLowerCase();

switch (command) {
case 'ls':
case 'list':
listDirectory(currentPath);
askCommand(currentPath);
break;

case 'cd':
const newPath = parts[1] ? path.resolve(currentPath, parts[1]) : process.cwd();
if (fs.existsSync(newPath) && fs.statSync(newPath).isDirectory()) {
askCommand(newPath);
} else {
console.log('Directory not found');
askCommand(currentPath);
}
break;

case 'pwd':
console.log(`Current directory: ${currentPath}`);
askCommand(currentPath);
break;

case 'cat':
if (parts[1]) {
const filePath = path.resolve(currentPath, parts[1]);
try {
const content = fs.readFileSync(filePath, 'utf8');
console.log(`\nContent of ${parts[1]}:`);
console.log('-'.repeat(30));
console.log(content);
} catch (error) {
console.log(`Error reading file: ${error.message}`);
}
} else {
console.log('Please specify a file name');
}
askCommand(currentPath);
break;

case 'quit':
case 'exit':
console.log('Goodbye!');
rl.close();
break;

case 'help':
console.log('\nAvailable commands:');
console.log(' ls, list - List directory contents');
console.log(' cd <dir> - Change directory');
console.log(' pwd - Show current directory');
console.log(' cat <file> - Display file contents');
console.log(' help - Show this help');
console.log(' quit, exit - Exit the program');
askCommand(currentPath);
break;

default:
console.log('Unknown command. Type "help" for available commands.');
askCommand(currentPath);
}
});
}

console.log('Welcome to Node.js File Explorer!');
console.log('Type "help" for available commands\n');

askCommand(process.cwd());

Step 2: Run the Application

node file-explorer.js

Sample Output:

Welcome to Node.js File Explorer!
Type "help" for available commands

[/home/user]> ls

Contents of: /home/user
==================================================
Type Size Modified Name
--------------------------------------------------
DIR - 12/20/2024 Documents
DIR - 12/22/2024 Downloads
DIR - 12/25/2024 nodejs-projects
FILE 1.2 KB 12/25/2024 hello.js
FILE 856 B 12/25/2024 package.json
--------------------------------------------------
Total: 5 items

[/home/user]> help

Available commands:
ls, list - List directory contents
cd <dir> - Change directory
pwd - Show current directory
cat <file> - Display file contents
help - Show this help
quit, exit - Exit the program

[/home/user]> quit
Goodbye!

Key Concepts Learned

Through these applications, you've learned:

  1. Console Output: Using console.log() for output
  2. User Input: Using readline module for interactive input
  3. File Operations: Reading and writing files with fs module
  4. HTTP Server: Creating web servers with http module
  5. URL Parsing: Handling different routes and query parameters
  6. Error Handling: Using try-catch blocks and error callbacks
  7. Process Information: Accessing system information via process object
  8. Module System: Using built-in Node.js modules

Best Practices

  1. Error Handling: Always handle errors in asynchronous operations
  2. Code Organization: Keep your code modular and well-structured
  3. Input Validation: Validate user input before processing
  4. Resource Management: Close file handles and server connections properly
  5. Security: Be careful with file system operations and user input

Next Steps

Now that you've created your first Node.js applications, you're ready to:

  1. Node.js - REPL Terminal - Learn the interactive Node.js shell
  2. Node.js - Command Line Options - Learn CLI parameters
  3. Node.js - Package Manager (NPM) - Learn package management
  4. Node.js - Callbacks Concept - Understand callback functions

First Application Complete! You've successfully created your first Node.js applications and learned the fundamental concepts. Ready to explore more advanced topics!