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 🙏

© 2026 – Pkg Stats / Ryan Hefner

biensure-nsh

v1.1.1

Published

A Node.js-based shell with REPL and script execution support.

Downloads

28

Readme


🐚 nsh — Node.js Shell

A REPL-powered Node.js shell that combines the flexibility of JavaScript with shell-like capabilities via ShellJS. Supports CLI, .nsh scripts, argument passing, async functions, REPL history and auto-complete, persistent variables and ShellJS based plugins.


📦 Install

Install globally via NPM:

npm install -g biensure-nsh

To run it locally (without installing globally):

npx nsh path/to/script.nsh

🚀 Usage

Launch Interactive Shell

nsh

You'll see a prompt like:

nsh:/your/current/directory >

Try some shell commands:

ls();
cd('code');
pwd();

These are available because ShellJS is loaded into the context of every .nsh script.

You can use any JavaScript too:

[1, 2, 3].map(x => x * 2);

Why the big output object?

The reason why, after typing ls(), you see a very big object like this:

nsh:/home/user/directory > ls()
[
  'LICENSE',
  'README.md',
  'node_modules',
  'nsh.js',
  'package-lock.json',
  'package.json',
  'test',
  stdout: 'LICENSE\n' +
    'README.md\n' +
    'node_modules\n' +
    'nsh.js\n' +
    'package-lock.json\n' +
    'package.json\n' +
    'test\n',
  stderr: null,
  code: 0,
  cat: [Function: bound ],
  exec: [Function: bound ],
  grep: [Function: bound ],
  head: [Function: bound ],
  sed: [Function: bound ],
  sort: [Function: bound ],
  tail: [Function: bound ],
  to: [Function: bound ],
  toEnd: [Function: bound ],
  uniq: [Function: bound ]
]

is because what you see is the output object from a ShellJS command. As you can see it contains stdout, stderr, code and some sub functions exec(), .sort()...

These can be quite handy, look:

nsh:/home/user/directory > ls().sort()
[String: 'LICENSE\n' +
  'node_modules\n' +
  'nsh.js\n' +
  'package-lock.json\n' +
  'package.json\n' +
  'README.md\n' +
  'test\n'] {
...
}

If don't want the big object and you only want the stdout just type:

console.log(ls().stdout);

Alternatively to get short ouput with the ShellJS command echo(); simply add undefined;:

echo("hello"); undefined;

Run a .nsh Script

nsh path/to/script.nsh

Or pass arguments:

nsh test/myscript.nsh hello world

📁 Script Example

// test/example.nsh

console.log("Hello from nsh script!");

// Access CLI args
args.forEach((a, i) => console.log(`arg[${i}] = ${a}`));

// Use shelljs commands
console.log('Directory listing:');
console.log(ls().stdout);

// Async support
await new Promise(r => setTimeout(r, 1000));
console.log("Waited 1 second.");

🧠 Passing Arguments to Scripts

Arguments passed on the command line are available as args:

nsh myscript.nsh foo bar
// inside myscript.nsh
console.log(args);  // ['foo', 'bar']

⏳ Async/Await Support

All .nsh scripts run inside an async IIFE. So you can:

✅ Use await at top-level ✅ Perform file operations, HTTP requests, etc.

const { readFile } = require('fs/promises');
const content = await readFile('README.md', 'utf-8');
console.log(content);

🧮 Persistent Variables

Variables defined in the REPL are persisted across commands during the session, just like in a regular JavaScript environment:

nsh
nsh:/home/user > var TESTVAR = 1;
nsh:/home/user > console.log(TESTVAR);
1
nsh:/home/user > echo(TESTVAR);
1
[String: '1\n'] {
  stdout: '1\n',
  stderr: null,
  code: 0,
  ...
}

These variables remain in memory until you exit the session. This makes it easy to store values, reuse them across shell and JS commands, and experiment interactively.

You can use both standard JavaScript functions and ShellJS utilities with your variables.


✨ Make .nsh Scripts Executable

To run .nsh scripts like regular shell scripts:

  1. Add a Shebang

At the very top of your .nsh script, add:

#!/usr/bin/env nsh
  1. Make It Executable

Give it execute permissions:

chmod +x yourscript.nsh
  1. Run It
./yourscript.nsh arg1 arg2

It will behave just like a Bash or Python script — but powered by Node.js and ShellJS.


💼 Customized commands pwdl and lsl

For testing purpose the pwdl() and lsl() command were added:

// Added a console logged `pwd` helper command `pwdl()`
console.log(pwd().stdout);

// Added a console logged `ls` helper command `lsl()`
console.log(ls().stdout);

This way the result was quite a bit shorter and directly effective.

Of courses you can wrap any ShellJS command in console.log() and choose to only log the error by adding .stderr instead of .stdout


🔌 Plugins

You can inject functionality into nsh via the plugin system of ShellJS. Every plugin installed in ShellJS will be available within nsh. Read the wiki about how to install, write and share plugins.


🧑‍💻 Author

Made by @biensurerodezee

MIT License


🛠️ Troubleshooting

  • Maximum Call Stack Size Exceeded: This can happen if there's an infinite loop or recursion in your script. Make sure your scripts are not recursively calling themselves or running into circular dependencies.
  • File Not Found: If you get an error saying File not found, ensure the script path is correct and the file exists.
  • Command Not Found: Ensure you’ve correctly added ShellJS commands, read the plugin wiki.

🤝 Contributing

You can extend or contribute to nsh by:

  • Sharing your-created.nsh scripts by adding them to the example/ folder and create a pull request.
  • Creating ShellJS based plugins to add custom functionality.
  • Opening an issue or submitting a pull request with any improvements.

✅ Test Coverage

The project includes a robust test suite (using Vitest) to validate:

  • ✅ Version output
  • ✅ Script execution with and without args
  • ✅ Async/await handling
  • ✅ Missing and invalid scripts
  • ✅ Runtime error messages
  • ✅ Script execution via REPL
  • ✅ Shebang handling
  • ✅ REPL prompt updates on cd
  • ✅ REPL history load/save

Tests are located in nsh.test.js and cover both CLI and REPL functionality.

This should give you a full understanding of how to use, extend, or even set up nsh as your default shell :). Let me know if anything is unclear or if you need further improvements!