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 consolenew 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 inputcreateInterface()
: Creates a readline interfacequestion()
: Prompts the user with a questionprocess.stdin
: Standard input streamprocess.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 operationswriteFile()
: Asynchronously writes data to a filereadFile()
: Asynchronously reads file contentsstat()
: Gets file statisticspath
: 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 pagehttp://localhost:3000/about
- About pagehttp://localhost:3000/api/info
- JSON API endpointhttp://localhost:3000/hello?name=John
- Hello page with query parameter
Step 4: Understanding the Code
http
: Built-in module for creating HTTP serversurl
: Module for parsing URLscreateServer()
: Creates an HTTP serverlisten()
: Starts the server on a specific portwriteHead()
: Sets response headersend()
: 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:
- Console Output: Using
console.log()
for output - User Input: Using
readline
module for interactive input - File Operations: Reading and writing files with
fs
module - HTTP Server: Creating web servers with
http
module - URL Parsing: Handling different routes and query parameters
- Error Handling: Using try-catch blocks and error callbacks
- Process Information: Accessing system information via
process
object - Module System: Using built-in Node.js modules
Best Practices
- Error Handling: Always handle errors in asynchronous operations
- Code Organization: Keep your code modular and well-structured
- Input Validation: Validate user input before processing
- Resource Management: Close file handles and server connections properly
- 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:
- Node.js - REPL Terminal - Learn the interactive Node.js shell
- Node.js - Command Line Options - Learn CLI parameters
- Node.js - Package Manager (NPM) - Learn package management
- 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!