Node.js: The commonly used NPM packages — Part 5

Mayank C
Tech Tonic

--

There is no denying that Node.js’s power comes from the 1.5M NPM packages. Without NPM, Node.js is still usable, but not much. In this article series, we will explore the commonly used NPM packages that every developer should be aware of. In this part, which is also the last part of this series, we’ll cover packages 41 to 50.

The other parts in this series are:

41. Ora

Ora is a powerful and versatile CLI spinner library for Node.js applications. It creates rich visual indicators of ongoing tasks, enhancing user experience and providing informative feedback during long-running processes.

Statistics

  • Weekly downloads: 22M
  • Size: 26 K
  • Files: 5

Code Samples

Basic Usage

const ora = require('ora');

const spinner = ora('Processing files...');
spinner.start();

// Perform your long-running task

spinner.succeed('Files processed successfully!');

Customization

const spinner = ora({
text: 'Downloading data...',
spinner: 'star',
color: 'cyan',
});

spinner.start();

// ...

spinner.fail('Downloading failed!');

Progress Tracking

const spinner = ora({
text: 'Compiling code...',
progress: true,
});

spinner.start();

// Perform your task with progress updates

spinner.succeed('Code compiled successfully!');

Pros

  • User-friendly and intuitive: Easy to integrate and utilize for developers of all skill levels.
  • Visually appealing spinners: Wide range of styles and customization options to create engaging user experiences.
  • Informative feedback: Keeps users informed about task progress and potential issues.
  • Lightweight and efficient: Minimal impact on application performance.

Cons

  • Limited pre-defined spinners: Some users might prefer an even broader selection of styles.
  • Customization learning curve: Advanced options might require exploring documentation and examples.

42. Faker

Faker is a popular Node.js library for generating realistic fake data, commonly used for testing, prototyping, and populating databases. It provides a wide range of functionalities, including:

  • Generating personal data: names, addresses, phone numbers, emails, avatars, and more.
  • Creating financial information: credit card numbers, bank account numbers, cryptocurrency addresses.
  • Simulating locations: geocoordinates, IP addresses, company names and logos.
  • Producing text content: sentences, paragraphs, poems, letters, and even blog posts.
  • Generating dates and times: timestamps, relative dates, date ranges.

Statistics

  • Weekly downloads: 3.8 M
  • Size: 10.2 M
  • Files: 5763

Code Samples

Generating a person

const faker = require('faker');

const person = {
name: faker.name.findName(),
address: faker.address.streetAddress(),
phone: faker.phone.phoneNumber(),
email: faker.internet.email(),
};

console.log(person);

Creating a company

const company = {
name: faker.company.companyName(),
slogan: faker.company.catchPhrase(),
address: faker.address.streetAddress(),
logo: faker.image.imageUrl(),
};

console.log(company);

Faker chain for product reviews

const reviews = [];

for (let i = 0; i < 10; i++) {
reviews.push({
author: faker.name.findName(),
rating: faker.random.number({ min: 1, max: 5 }),
content: faker.commerce.productReview(),
});
}

console.log(reviews);

Pros

  • Rich data options: Caters to a wide range of data generation needs.
  • Customization control: Tailors data to specific contexts and requirements.
  • Ease of use: Simple API and readily available examples.
  • Testing efficiency: Saves time and effort in test data creation.
  • Data privacy: Generates non-identifiable data, protecting user privacy.

Cons

  • Potential for randomness overload: Data might not always feel truly “real.”
  • Limited control over individual fields: Customization applies to data types, not specific fields.

43. Puppeteer

Puppeteer is a powerful Node.js library that provides control over Chrome or Chromium browsers through the DevTools Protocol. It enables developers to automate tasks like:

  • Web scraping: Extracting data from websites dynamically.
  • UI testing: Automating browser interactions for testing web applications.
  • Generating screenshots and PDFs: Capturing visual representations of web pages.
  • Crawling and rendering: Navigating and processing single-page applications (SPAs).
  • Controlling browser behavior: Executing JavaScript within the browser environment.

Statistics

  • Weekly downloads: 4.3 M
  • Size: 329 K
  • Files: 43

Code Samples

Scraping product details

const puppeteer = require('puppeteer');

(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.goto('https://example.com/products/123');

const title = await page.$eval('.product-title', el => el.textContent);
const price = await page.$eval('.product-price', el => el.textContent);

console.log(`Title: ${title}`);
console.log(`Price: ${price}`);

await browser.close();
})();

Taking screenshots

const puppeteer = require('puppeteer');

(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.goto('https://example.com');

await page.screenshot({ path: 'screenshot.png' });

await browser.close();
})();

Running JavaScript in the browser

const puppeteer = require('puppeteer');

(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();

const result = await page.evaluate(() => document.title);

console.log(`Page title: ${result}`);

await browser.close();
})();

Pros

  • Powerful and versatile: Handles various automation tasks beyond simple browser control.
  • Headless capabilities: Enables automation without affecting user experience.
  • Well-maintained and documented: Actively developed with extensive documentation and community support.
  • Flexible scripting: Allows tailoring automation scenarios to specific needs.
  • Wide range of applications: Useful for web development, testing, scraping, and more.

Cons

  • Learning curve: Requires understanding of JavaScript and web development concepts.
  • Headless complexity: Debugging headless browser issues can be challenging.
  • Resource intensive: Running Chrome/Chromium can have performance implications.
  • Potential for misuse: Scraping websites might violate terms and conditions.

44. CSV

csv is a fairly popular NPM package for Node.js, specializing in handling Comma-Separated Values (CSV) data. It provides functionalities for:

  • Parsing CSV files: Converts textual CSV data into arrays or objects.
  • Stringifying data: Generates CSV content from JavaScript objects or arrays.
  • Transforming data: Manipulates and adjusts data within the CSV structure.
  • Streaming large datasets: Handles efficient processing of big CSV files without memory overload.
  • Customizable options: Adjust parsing and stringifying behavior for specific needs.

Statistics

  • Weekly downloads: 1.1 M
  • Size: 2 M
  • Files: 20

Code Samples

Parsing a CSV file

const csv = require('csv');

const data = [];

csv.parse(fs.readFileSync('data.csv'), (err, row) => {
if (err) {
console.error(err);
} else {
data.push(row);
}
});

console.log(data); // Array of arrays representing CSV rows

Stringifying data to CSV

const csv = require('csv');

const users = [
{ name: 'John Doe', age: 30 },
{ name: 'Jane Doe', age: 25 },
];

const csvString = csv.stringify(users);

console.log(csvString); // Generated CSV string with user data

Transforming data with a custom function

const csv = require('csv');

const transformAge = (row) => ({ ...row, age: Number(row.age) + 1 });

csv.parse('data.csv', { transform: transformAge }, (err, data) => {
// data now contains modified age values
});

Pros:

  • Widely used and reliable: A mature and trusted package for CSV handling.
  • Feature-rich and versatile: Offers comprehensive functionalities for various needs.
  • Efficient and scalable: Handles large datasets effectively with streaming capabilities.
  • Easy to use: Simple API with straightforward methods and options.

Cons:

  • Potential complexity: Advanced features might require deeper understanding of parsing and transformation concepts.
  • Limited native formatting: Doesn’t handle complex formatting within CSV cells.

45. Pdfkit

Pdfkit excels in creating PDF documents programmatically. It offers a streamlined API for generating visually appealing and feature-rich PDFs, making it a popular choice for various applications.

Statistics

  • Weekly downloads: 500 K
  • Size: 5M
  • Files: 27

Code Samples

Creating a basic PDF

const PDFDocument = require('pdfkit');

const doc = new PDFDocument();

doc.text('Hello, PDF world!');
doc.pipe(fs.createWriteStream('output.pdf'));
doc.end();

Adding formatting and images

doc
.fontSize(24)
.text('Header', 150, 40)
.image('path/to/image.jpg', { fit: [250, 250] })
.moveDown(40)
.text('This is some formatted text.', { bold: true })
.moveDown(20);

Creating a multi-page document

doc.addPage();
doc.text('This is on a new page.');

Pros

  • Ease of use: Straightforward API for easy PDF creation.
  • Comprehensive features: Covers essential PDF elements and formatting options.
  • Customizable: Adjusts PDF properties and layout to match specific needs.

Cons

  • Limited high-level features: Lacks built-in support for advanced features like watermarks, digital signatures, or annotations.
  • Dependency on external libraries: Requires additional packages for font installation and image processing.

46. Pino

Pino is a highly performant logging library for Node.js applications. It prioritizes speed and efficiency while offering a rich set of features for structured and informative logging. Pino empowers developers to:

  • Log messages efficiently: Leverages a binary format for minimal performance impact on applications.
  • Structure log data: Organizes log entries into key-value pairs for enhanced readability and analysis.
  • Control log levels: Sets different verbosity levels (debug, info, warn, error) to target relevant information.
  • Customize log output: Formats logs in various formats like text, JSON, and pretty-printed formats.

Statistics

  • Weekly downloads: 6.2 M
  • Size: 689 K
  • Files: 190

Code Samples

Basic logging with pino

const pino = require('pino');

const logger = pino();

logger.info('Application started successfully.');
logger.warn('Unexpected error occurred during processing.');
logger.error('Critical failure, shutting down application.');

Structured logging with key-value pairs

logger.info({
user: 'John Doe',
action: 'File uploaded',
filename: 'image.png',
});

Customizing log format

const pretty = require('pino-pretty');

const logger = pino({ pretty: pretty });

logger.info('This log message will be prettified!');

Pros

  • Performance-focused: Minimizes impact on application speed and resource usage.
  • Structured and clear logs: Improves log readability and analysis through key-value pairs.
  • Flexible and customizable: Adapts to different logging needs and formats.
  • Wide range of integrations: Connects seamlessly with various platforms and tools.

Cons

  • Binary format complexity: Understanding and debugging binary logs might require additional effort.
  • Learning curve: Initial setup and customization can involve some learning.
  • Limited native filtering: Built-in filtering options might be insufficient for complex scenarios.

47. Passport

Passport.js is a middleware for implementing authentication in web applications. It provides a flexible and modular framework for integrating various authentication strategies, allowing you to:

  • Authenticate users: Verify user credentials against different sources like databases, social providers, or custom mechanisms.
  • Manage user sessions: Establish and manage secure user sessions after successful authentication.
  • Protect routes: Restrict access to specific routes based on user authorization levels.
  • Support multiple strategies: Integrate different authentication methods like email/password, social logins, OAuth, or token-based approaches.
  • Extendable and customizable: Tailor authentication and authorization workflows to your specific application needs.

Statistics

  • Weekly downloads: 2.3 M
  • Size: 157 K
  • Files: 21

Code Samples

Basic passport setup with email/password authentication

const express = require('express');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

const app = express();

// Define user authentication logic
passport.use(new LocalStrategy((username, password, done) => {
// ... verify username and password against your database
if (valid) {
done(null, user);
} else {
done(null, false);
}
}));

// Set up session management
app.use(passport.session());
app.use(passport.initialize());

// Protect a specific route (e.g., dashboard)
app.get('/dashboard', passport.authenticate('local', { failureRedirect: '/login' }), (req, res) => {
res.send('Welcome to the dashboard!');
});

app.listen(3000, () => console.log('Server running on port 3000'));

Integrating social login with Facebook

const FacebookStrategy = require('passport-facebook').Strategy;

passport.use(new FacebookStrategy({
clientID: 'YOUR_FACEBOOK_APP_ID',
clientSecret: 'YOUR_FACEBOOK_APP_SECRET',
callbackURL: 'https://yourdomain.com/auth/facebook/callback',
}, (accessToken, refreshToken, profile, done) => {
// ... process Facebook profile data and handle user creation/login
done(null, user);
}));

Pros

  • Flexibility and control: Supports various authentication methods and allows customization to specific needs.
  • Modular and extendable: Integrates seamlessly with other modules and offers plugin flexibility.
  • Secure and reliable: Implements industry standards and best practices for user authentication.
  • Large community and resources: Comprehensive documentation, active community, and readily available plugins.
  • Wide range of applications: Suitable for various web applications requiring user authentication and authorization.

Cons

  • Initial setup complexity: Configuring passport and authentication strategies might require some learning.
  • Security considerations: Implementing secure authentication practices requires careful planning and adherence to best practices.
  • Potential vulnerability attacks: Requires attention to potential security vulnerabilities in chosen authentication methods.

48. Ejs

ejs (Embedded JavaScript templates) is a popular template engine that allows you to seamlessly integrate dynamic content within HTML templates. It provides a simple and efficient way to:

  • Generate dynamic HTML: Inject values from JavaScript variables and objects into your HTML templates.
  • Control flow with logic: Utilize conditional statements and loops to control content display based on data or user actions.
  • Maintain code separation: Keep your HTML clean and focused on presentation, while logic resides in separate JavaScript files.
  • Enhance reusability: Create reusable templated components for consistent page elements.
  • Server-side and client-side rendering: Choose between server-side rendering for SEO and pre-loading, or client-side rendering for interactive applications.

Statistics

  • Weekly downloads: 14 M
  • Size: 142 K
  • Files: 13

Code Samples

Basic ejs template with dynamic content

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome, <%= user.name %>!</title>
</head>
<body>
<h1>Hello, world!</h1>
<p>Today is <%= new Date().toLocaleDateString() %>. You have <%= user.points %> points.</p>
</body>
</html>

Handling Data and Loops

// product.ejs

<h1>Product Listing</h1>
<ul>
<% for (const product of products) { %>
<li>
<h3><%= product.name %></h3>
<p>Price: <%= product.price %> USD</p>
</li>
<% } %>
</ul>

// app.js
// ... (express setup as in previous example)

const products = [
{ name: 'Product A', price: 9.99 },
{ name: 'Product B', price: 14.50 },
{ name: 'Product C', price: 22.95 }
];

app.get('/products', (req, res) => {
res.render('products', { products });
});

Implementing Conditional Logic

// user.ejs

<% if (user.isLoggedIn) { %>
<p>Welcome back, <%= user.username %>!</p>
<a href="/logout">Logout</a>
<% } else { %>
<p>Please <a href="/login">login</a> or <a href="/register">register</a>.</p>
<% } %>

// app.js

// ... (express setup as in previous examples)

const user = {
isLoggedIn: true, // or false
username: 'exampleUser' // or null
};

app.get('/user', (req, res) => {
res.render('user', { user });
});

Pros

  • Simple and easy to learn: Requires minimal JavaScript knowledge for basic usage.
  • Efficient and clean code: Separates presentation logic from HTML, fostering maintainable codebases.
  • Flexible and versatile: Handles various dynamic content scenarios and rendering approaches.
  • Lightweight and performant: Minimal impact on application performance.

Cons

  • Security considerations: Improper template sanitization can introduce security vulnerabilities.
  • Limited built-in functionalities: Requires additional libraries for complex tasks like form handling or routing.
  • Potential XSS vulnerabilities: Be aware of potential cross-site scripting vulnerabilities when injecting user-generated content.

49. Cheerio

Cheerio is a server-side implementation of a subset of jQuery, designed for parsing and manipulating HTML in Node.js environments. It provides a familiar syntax and API for navigating, selecting, and modifying elements within HTML structures, making it a powerful tool for tasks like:

  • Web scraping: Extracting data from websites without a browser.
  • HTML testing: Creating and testing HTML snippets without a full browser setup.
  • Server-side rendering: Generating HTML content on the server for improved SEO and performance.

Statistics

  • Weekly downloads: 7.4 M
  • Size: 558 K
  • Files: 124

Code Samples

Selecting and manipulating elements

const cheerio = require('cheerio');
const html = '<h2 class="title">Hello, world!</h2>';

const $ = cheerio.load(html);
const title = $('.title').text(); // Get text content of the h2 element
$('.title').text('Goodbye, world!'); // Change the text content
console.log(title); // Output: "Hello, world!"

Extracting data

const html = '<ul><li>Item 1</li><li>Item 2</li></ul>';
const $ = cheerio.load(html);
const items = $('li').map((i, el) => $(el).text()).get(); // Get text content of all li elements
console.log(items); // Output: ["Item 1", "Item 2"]

Pros

  • Easy to learn: Familiar syntax for those with jQuery experience.
  • Fast and efficient: Optimized for server-side performance.
  • Powerful selectors: Versatile element targeting capabilities.
  • Chainable methods: Concise and expressive code.
  • Event simulation: Basic testing capabilities.
  • Customizable: Extendable with plugins.

Cons

  • Not a full browser environment: Lacks some browser-specific features.
  • Limited event handling: Basic simulation for testing purposes.
  • Potential security risks: Be cautious with untrusted HTML input.

50. Grunt

Grunt is a JavaScript task runner that automates repetitive tasks in web development workflows. It uses a configuration file (Gruntfile) to define tasks and plugins, streamlining processes like:

  • Compilation and minification: Transforming code into optimized, production-ready versions.
  • Linting: Enforcing code quality standards and identifying potential errors.
  • Testing: Running automated tests to ensure code correctness.
  • Concatenation and minification: Combining and compressing files for faster loading.
  • Deployment: Publishing code to a web server or other environments.
  • Watching for file changes: Automatically re-running tasks when files are modified.

Statistics

  • Weekly downloads: 814 K
  • Size: 68 K
  • Files: 51

Code Samples

Minifying JavaScript files

// Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
// Optional UglifyJS options
},
my_target: {
files: {
'dist/output.min.js': ['src/**/*.js'] // Minify all JS files in src directory
}
}
}
});

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['uglify']);
};

Lint JavaScript files

// Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jshint: {
options: {
// JSHint options
},
all: ['src/**/*.js'] // Lint all JS files in src directory
}
});

grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('default', ['jshint']);
};

Watch for file changes and run tasks

// Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
// ... other tasks
watch: {
scripts: {
files: ['src/**/*.js'], // Watch JS files in src directory
tasks: ['uglify', 'jshint'] // Run tasks when files change
}
}
});

// ... load plugins
grunt.registerTask('default', ['watch']);
};

Pros

  • Extensive plugin ecosystem: Wide range of pre-built functionality.
  • Flexible configuration: Customize tasks to specific needs.
  • Watch mode: Automates repetitive tasks during development.
  • Parallel task execution: Improves efficiency.

Cons

  • Configuration overhead: Initial setup can require effort.
  • Plugin compatibility: Potential issues with plugin versioning and compatibility.
  • Alternatives like Gulp: Other task runners offer different approaches and features.

That’s all about the packages for this article.

The other parts in this series are:

--

--