| name | nodejs |
| description | JavaScript runtime built on Chrome's V8 JavaScript engine |
| category | web-development |
| difficulty | intermediate |
| tags | ["runtime","javascript","server-side","async"] |
| author | OpenJS Foundation |
| version | 21 |
| last_updated | 2024-01-15T00:00:00.000Z |
Node.js
What I Do
I am Node.js, a JavaScript runtime built on Chrome's V8 engine that enables JavaScript execution outside the browser. I provide an event-driven, non-blocking I/O model that makes me exceptionally efficient for building scalable network applications. My architecture excels at handling concurrent connections with minimal overhead, making me ideal for real-time applications, APIs, and microservices. I run JavaScript code with access to the file system, network requests, child processes, and operating system functionality. My npm ecosystem is the largest package registry in the world, providing millions of reusable packages. I support modern JavaScript features through native ECMAScript module support and experimental features. My HTTP server capabilities built into the standard library enable quick prototyping and production deployment without external dependencies. My worker threads provide true parallelism for CPU-intensive tasks while maintaining the event loop model.
When to Use Me
- Building RESTful APIs and GraphQL servers
- Real-time applications (chat, gaming, collaboration)
- Microservices architecture
- Server-side rendering (Next.js, Nuxt)
- Command-line tools and CLI applications
- Build tools and task runners (Webpack, Vite)
- Desktop applications (Electron)
- IoT applications and streaming services
- Proxy servers and API gateways
- Any JavaScript-heavy backend development
Core Concepts
Event Loop: My single-threaded execution model that processes asynchronous operations in phases, allowing non-blocking I/O while handling thousands of concurrent connections.
Non-blocking I/O: Operations like file reads, network requests, and database queries don't block the main thread, enabling concurrent processing.
CommonJS Modules: The traditional module system using require() and module.exports for organizing code.
ES Modules: Modern JavaScript module syntax with import and export, supported natively in Node.js 14+.
Streams: Abstract interface for working with streaming data, enabling memory-efficient processing of large files and network data.
Buffers: Raw binary data handling for working with binary protocols, file systems, and network packets.
Child Processes: Spawning and managing subprocesses for CPU-intensive tasks and system integration.
Worker Threads: True parallelism for CPU-bound JavaScript code while sharing memory with the main thread.
Code Examples
Example 1: Asynchronous HTTP Server with Middleware
const http = require('http')
const { EventEmitter } = require('events')
class KoaRouter {
constructor() {
this.layers = []
}
get(path, handler) {
this.layers.push({ method: 'GET', path, handler })
return this
}
post(path, handler) {
this.layers.push({ method: 'POST', path, handler })
return
}
async handle(ctx) {
for (const layer of this.layers) {
if (ctx.method === layer.method && ctx.path === layer.path) {
return layer.handler(ctx)
}
}
ctx.status = 404
ctx.body = { error: 'Not Found' }
}
}
{
() {
. = req
. = res
. = req.
. = (req., ).
. = .(
(req., ).
)
. = {}
. =
. =
}
() {
. = data
..(, )
}
}
{
() {
()
. = ()
. = []
}
() {
..(fn)
}
() {
..(path, handler)
}
() {
..(path, handler)
}
() {
ctx = (req, res)
( fn .) {
(ctx)
(ctx..)
}
..(ctx)
res. = ctx.
res.(.(ctx.))
}
() {
server = http.(..())
server.(...args)
}
}
app = ()
app.( (ctx) => {
start = .()
( ctx..(, resolve))
ms = .() - start
.()
})
app.(, (ctx) => {
ctx.({ : , : ().() })
})
app.(, (ctx) => {
ctx..
ctx.({ : ctx.., : + ctx.. })
})
app.(, {
.()
})
Example 2: File Streams and Pipe Operations
const fs = require('fs')
const { pipeline } = require('stream/promises')
const { createGzip, createGunzip } = require('zlib')
const { Transform } = require('stream')
class LineCounter extends Transform {
constructor(options = {}) {
super({ ...options, objectMode: true })
this.lineCount = 0
}
_transform(chunk, encoding, callback) {
const lines = chunk.toString().split('\n')
if (!this.lastChunk) {
this.lineCount += lines.length - 1
} else {
this.lineCount += lines.length
}
this.lastChunk = chunk
callback(null, { lines: chunk.toString().split(), : . })
}
}
{
() {
({ : })
. =
}
() {
lines = chunk.
(!. && lines. > ) {
. = lines[].()
lines.()
}
records = lines
.( line.())
.( {
values = line.()
..( {
obj[header.()] = values[i]?.()
obj
}, {})
})
(, records)
}
}
() {
readStream = fs.(inputPath)
writeStream = fs.(outputPath)
gzip = ()
lineCounter = ()
csvToJson = ()
readStream
.(lineCounter)
.(csvToJson)
.(gzip)
.(writeStream)
(readStream, lineCounter, csvToJson, gzip, writeStream)
.()
}
() {
gzip = ()
input = fs.(gzipPath)
output = fs.(outputPath)
(input, gzip, output)
.()
}
Example 3: Worker Threads for CPU-Intensive Tasks
const {
Worker, isMainThread, parentPort, workerData
} = require('worker_threads')
if (isMainThread) {
class ThreadPool {
constructor(size = navigator.hardwareConcurrency) {
this.size = size
this.workers = []
this.queue = []
this.active = 0
}
run(task) {
return new Promise((resolve, reject) => {
const worker = this.findAvailableWorker()
if (worker) {
this.execute(worker, task, resolve, reject)
} else {
this.queue.push({ task, resolve, reject })
}
})
}
findAvailableWorker() {
if (this.active < this.size) {
this.active++
return new Worker(__filename)
}
}
() {
worker.({ task })
worker.(, {
(result)
.--
worker.()
.()
})
worker.(, reject)
}
() {
(.. > ) {
{ task, resolve, reject } = ..()
worker = .()
(worker) {
.(worker, task, resolve, reject)
} {
..({ task, resolve, reject })
}
}
}
}
() {
(n <= ) n
(n - ) + (n - )
}
pool = ()
() {
.()
results = .([
pool.({ : , : [] }),
pool.({ : , : [] }),
pool.({ : , : [] }),
pool.({ : , : [] })
])
.()
.(, results)
}
()
} {
parentPort.(, {
{ fn, args } = msg.
result = ()[fn](...args)
parentPort.(result)
})
}
Example 4: Database Connection Pool with Promise Wrapper
const { createPool, Pool } = require('pg')
class Database {
constructor(config) {
this.pool = new Pool(config)
this.pool.on('error', (err) => {
console.error('Unexpected database error:', err)
})
}
async query(text, params = []) {
const start = Date.now()
try {
const result = await this.pool.query(text, params)
const duration = Date.now() - start
console.log('Query executed:', { text: text.substring(0, 100), duration, rows: result.rowCount })
return result
} catch (error) {
console.error('Query error:', { : text.(, ), : error. })
error
}
}
() {
client = ..()
originalRelease = client..(client)
released =
client. = {
(released)
released =
client.().( ())
}
client
}
() {
client = .()
{
client.()
result = (client)
client.()
result
} (error) {
client.()
error
} {
client.()
}
}
() {
..()
}
}
{
() {
. = db
}
() {
result = ..(
,
[id]
)
result.[] ||
}
() {
result = ..(
,
[email]
)
result.[] ||
}
() {
{ name, email, passwordHash } = data
result = ..(
,
[name, email, passwordHash]
)
result.[]
}
() {
fields = .(data)
values = .(data)
setClause = fields.( ).()
result = ..(
,
[id, ...values]
)
result.[] ||
}
() {
result = ..(, [id])
result. >
}
}
db = ({
: process.. || ,
: ,
: process..,
: process..,
: ,
: ,
:
})
users = (db)
Example 5: Real-time Event Bus with Pub/Sub
const { EventEmitter } = require('events')
class EventBus extends EventEmitter {
constructor(options = {}) {
super()
this.subscriptionCount = new Map()
this.middleware = options.middleware || []
this.setMaxListeners(Infinity)
}
async publish(topic, data, metadata = {}) {
const context = {
topic,
data,
metadata: {
...metadata,
timestamp: new Date().toISOString(),
source: metadata.source || 'unknown'
}
}
for (const fn of this.middleware) {
await fn(context)
}
this.emit(topic, context)
return context
}
subscribe(topic, handler, options = {}) {
const listener = () => {
{
(context., context.)
(options. !== ) {
.(, { topic, : handler. })
}
} (error) {
.(, { topic, error, context })
(options. !== ) {
( .(topic, handler, { ...options, : }), )
}
}
}
listener. = handler
.(topic, listener)
count = ..(topic) ||
..(topic, count + )
.(topic, listener)
}
() {
.(topic, handler)
count = ..(topic) ||
..(topic, count - )
}
() {
{
: ..,
: .(..()).( a + b, ),
: .()
}
}
}
{
() {
}
() {
context.. = context.. || .()
}
}
{
() {
.(, {
: context..,
: context. === ? .(context.) : context.
})
}
}
eventBus = ({
: [ (), ()]
})
eventBus.(, (user) => {
.(, user.)
eventBus.(, { user })
})
eventBus.(, (data) => {
.(, data..)
})
eventBus.(, {
: ,
: ,
:
})
unsubscribe = eventBus.(, {
.(, user.)
})
Best Practices
- Use async/await over callbacks for better readability and error handling
- Implement proper error handling with try/catch and domain error boundaries
- Use environment variables for configuration (dotenv package)
- Keep the event loop healthy by offloading CPU-intensive work to worker threads
- Use streams for handling large files and data sets
- Implement connection pooling for databases and external services
- Gracefully handle uncaught exceptions and promise rejections
- Use clustering to utilize multi-core systems for production
- Monitor memory usage and identify leaks with heap snapshots
- Use
--inspect flag for debugging with Chrome DevTools
Core Competencies
- Event-driven, non-blocking I/O architecture
- HTTP server and client implementation
- File system operations with streams
- Child processes and worker threads
- npm package management
- ES modules and CommonJS interoperability
- Async programming patterns (callbacks, promises, async/await)
- Real-time communication with WebSocket
- Database connectivity and ORM integration
- CLI application development
- Testing with Jest, Mocha, and Supertest
- Security best practices (input validation, rate limiting)