npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

njshell

v2.0.1

Published

Lightweight shell command executor for Node.js - Support for multiple output formats (string, buffer, stream, vinyl), local npm binaries, timeout controls, and Gulp integration.

Readme

njshell

CI npm version npm downloads license

Lightweight shell command executor for Node.js - Support for multiple output formats (string, buffer, stream, vinyl), local npm binaries, timeout controls, and Gulp integration.

Lightweight utility for running shell commands from Node.js with support for multiple output types: string, buffer, stream, and vinyl (for Gulp pipelines).

Features

  • ✅ Multiple output formats (string, buffer, stream, vinyl)
  • ✅ Async/Promise-based API
  • ✅ Local npm binary execution
  • ✅ Timeout and signal support
  • ✅ Gulp/Vinyl integration
  • ✅ Windows support
  • ✅ TypeScript-friendly JSDoc
  • ✅ Zero configuration

Installation

npm install njshell

Quick Start

const { exec, execLocal } = require('njshell');

// Execute command and get output as string
const version = await exec('node --version');
console.log(version); // "v20.10.0"

// Run local npm binary
const lintResult = await execLocal('eslint src/**/*.js');
console.log(lintResult);

API

exec(command, type, filename, options)

Execute a shell command with flexible output format.

Parameters:

  • command (string) - Command to execute
  • type (string) - Output format: 'string' (default), 'buffer', 'stream', or 'vinyl'
  • filename (string) - Required when type is 'vinyl'
  • options (object) - Execution options

Options:

  • cwd (string) - Current working directory
  • encoding (string) - Output encoding (default: 'utf8')
  • timeout (number) - Timeout in milliseconds (default: 0 = no timeout)
  • maxBuffer (number) - Maximum stdout/stderr size (default: 10MB)
  • signal (AbortSignal) - AbortSignal for cancellation

Returns: Promise<string|Buffer|Readable|Stream>


execLocal(binary, type, filename, options)

Execute a local npm binary from node_modules/.bin/.

Parameters:

  • binary (string) - Binary name (e.g., 'eslint', 'webpack')
  • type (string) - Output format (same as exec)
  • filename (string) - Required when type is 'vinyl'
  • options (object) - Execution options (same as exec)

Returns: Promise<string|Buffer|Readable|Stream>


Usage Examples

String Output (Default)

Get command output as a trimmed string:

const { exec } = require('njshell');

// Get Node.js version
const version = await exec('node --version');
console.log(version); // "v20.10.0"

// Get directory listing
const files = await exec('ls -la');
console.log(files);

// Get package version from npm
const pkgVersion = await exec('npm view njshell version');
console.log(`Current version: ${pkgVersion}`);

Buffer Output

Get raw binary output:

const { exec } = require('njshell');

// Get file contents as buffer
const buffer = await exec('cat image.png', 'buffer');
console.log(buffer); // <Buffer 89 50 4e 47...>

// Process binary data
const compressed = zlib.gzipSync(buffer);

Stream Output

Get output as a readable stream:

const { exec } = require('njshell');
const fs = require('fs');

// Stream large file
const stream = await exec('cat large-file.txt', 'stream');
stream.pipe(fs.createWriteStream('output.txt'));

// Process stream data
stream.on('data', (chunk) => {
  console.log(`Received ${chunk.length} bytes`);
});

stream.on('end', () => {
  console.log('Stream completed');
});

Vinyl Output (Gulp Integration)

Create vinyl files for Gulp pipelines:

const { exec } = require('njshell');
const gulp = require('gulp');

async function buildStats() {
  // Run webpack and get stats as vinyl file
  const vinylStream = await exec('webpack --json', 'vinyl', 'webpack-stats.json');

  return vinylStream.pipe(gulp.dest('dist'));
}

exports.stats = buildStats;

Local Binaries

Execute npm binaries from node_modules/.bin/:

const { execLocal } = require('njshell');

// Run ESLint
const lintResult = await execLocal('eslint src/**/*.js');
console.log(lintResult);

// Run Webpack
const buildOutput = await execLocal('webpack --mode production');
console.log(buildOutput);

// Run TypeScript compiler
const tscOutput = await execLocal('tsc --noEmit');
console.log(tscOutput);

Advanced Options

Use execution options for better control:

const { exec } = require('njshell');

// Set working directory
const result = await exec('npm install', 'string', null, {
  cwd: '/path/to/project',
});

// Set timeout (5 seconds)
try {
  await exec('long-running-command', 'string', null, {
    timeout: 5000,
  });
} catch (err) {
  console.error('Command timed out');
}

// Use AbortController for cancellation
const controller = new AbortController();

setTimeout(() => controller.abort(), 3000);

try {
  await exec('sleep 10', 'string', null, {
    signal: controller.signal,
  });
} catch (err) {
  console.error('Command aborted');
}

// Increase buffer size for large output
const largeOutput = await exec('cat huge-file.txt', 'string', null, {
  maxBuffer: 50 * 1024 * 1024, // 50MB
});

Error Handling

Handle command execution errors:

const { exec } = require('njshell');

try {
  const result = await exec('invalid-command');
} catch (err) {
  console.error('Command failed:', err.message);
  console.error('stderr:', err.stderr);
  console.error('stdout:', err.stdout);
}

Gulp Build Pipeline

Complete Gulp integration example:

const { src, dest, series } = require('gulp');
const { exec, execLocal } = require('njshell');

async function lint() {
  const result = await execLocal('eslint src/**/*.js');
  console.log(result);
}

async function build() {
  const output = await execLocal('webpack --mode production');
  console.log(output);
}

async function generateDocs() {
  const docStream = await exec('jsdoc src -r -d docs', 'vinyl', 'docs/index.html');
  return docStream.pipe(dest('dist'));
}

exports.default = series(lint, build, generateDocs);

Output Types

'string' (Default)

Returns trimmed UTF-8 string. Best for text output.

const text = await exec('echo "Hello World"');
// Returns: "Hello World"

'buffer'

Returns Buffer object. Best for binary data.

const buffer = await exec('cat image.png', 'buffer');
// Returns: <Buffer 89 50 4e 47...>

'stream'

Returns Readable stream. Best for large outputs.

const stream = await exec('cat large.log', 'stream');
// Returns: Readable stream

'vinyl'

Returns vinyl file stream. Best for Gulp pipelines.

const vinylStream = await exec('build-output', 'vinyl', 'output.json');
// Returns: Vinyl stream for Gulp

Requirements

  • Node.js >= 18.0.0

Changelog

v2.0.1 (2025)

  • 🚀 Updated config files to latest standards
  • 🚀 Improved development workflow
  • 🚀 Better code quality tools
  • 🚀 Updated SEO-friendly package description

v2.0.0 (2024)

  • 🚀 BREAKING: Requires Node.js 18+
  • 🚀 BREAKING: Main file renamed from main.js to index.js
  • ✨ Added execution options (cwd, timeout, maxBuffer, signal)
  • ✨ Better error handling with stderr/stdout attachment
  • ✨ Windows support for execLocal (.cmd extension)
  • ✨ Improved vinyl file path handling
  • 🐛 Fixed console.log noise (now uses console.warn for stderr)
  • 🐛 Fixed vinyl path resolution
  • 📚 Comprehensive JSDoc documentation
  • 🔧 Updated dependencies (njfs 2.0, vinyl 3.0)

v1.1.2 (2020)

  • Previous stable release

Migration from v1.x

// v1.x - Basic usage (still works)
const result = await exec('npm --version');

// v2.x - With options
const result = await exec('npm --version', 'string', null, {
  cwd: '/path/to/project',
  timeout: 5000,
});

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Troubleshooting

When you encounter a problem, please open an issue.

Author

Orçun Saltık

License

MIT © Orçun Saltık