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

@jeremyjonas/runjs

v4.0.0

Published

Minimalistic building tool

Readme

runjs node version Build Status npm version Gitter

Minimalistic building tool

Get started

Install globally (for a command line script):

npm install runjs -g

Install in your project (to use runjs api inside your runfile.js):

npm install runjs --save-dev

If you want to use Babel, install it. RunJS will pickup your babel-register automatically.

npm install babel-core babel-preset-es2015 babel-register --save-dev

Configure Babel in your package.json:

"babel": {
  "presets": ["es2015"]
}

Create runfile.js:


import {run} from 'runjs';

export const build = {
  js () {
    run('webpack -p --config config/webpack/prod.js --progress');
  },
  
  css () {
    
  },
  
  all () {
    build.js()
    build.css()
  }
}

export function createcomponent (name) {
  
}

export function lint (path = '.', options = {}) {
  options.fix ? run(`eslint ${path} --fix`) : run(`eslint ${path}`) 
}

Run:

run createcomponent AppContainer
run build:js
run build:all
run lint --fix compontets/Button.js

Mechanism of RunJS is very simple. Tasks are run by just importing runfile.js as a normal node.js module. Then based on command line arguments a proper exported function from runfile.js is run.

Why runjs ?

We have Grunt, Gulp, npm scripts, Makefile. Why another building tool ?

Gulp or Grunt files seem overly complex for what they do and the plugin ecosystem adds a layer of complexity towards the simple command line tools underneath. The documentation is not always up to date and the plugin does not always use the latest version of the tool. After a while customizing the process even with simple things, reconfiguring it becomes time consuming.

Npm scripts are simple but they get out of hand pretty quickly if we need more complex process which make them quite hard to read.

Makefiles are simple, better for more complex processes but they depend on bash scripting. Within runfile you can use command line calls as well as JavaScript code and npm libraries which makes that approach much more flexible. Additionally each task and command call is reported in the console.

Handling arguments

Provided arguments in the command line are passed to the function:

export function sayHello (who) {
  console.log(`Hello ${who}!`)
}
$ run sayHello world
Hello world!

You can also provide dash arguments like -a or --test. Order of them doesn't matter after task name but they will be always passed as a last argument in a form of JSON object.

export function sayHello (who, options) {
  console.log(`Hello ${who}!`)
  console.log('Given options:', options)
}
$ run sayHello -a --test=something world
Hello world!
Given options: { a: true, test: 'something' }

API

For inside runfile.js usage

import {run, generate} from 'runjs';

run(cmd, options)

run given command as a child process and log the call in the output. ./node_modules/.bin/ is included into PATH so you can call installed scripts directly.

Options:

{
    cwd: ..., // current working directory (String)
    async: ... // run command asynchronously (true/false), false by default
    stdio: ... // 'inherit' (default), 'pipe' or 'ignore'
    env: ... // environment key-value pairs (Object)
    timeout: ...
}

Examples:

To get an output from run function we need to set stdio option to pipe otherwise output will be null:

const output = run('ls -la', {stdio: 'pipe'})
run('http-server .', {async: true, stdio: 'pipe'}).then((output) => {
  log(output) 
}).catch((error) => {
  throw error
})

For stdio: 'pipe' outputs are returned but not forwarded to the parent process thus not printed out to the terminal. For stdio: 'inherit' (default) outputs are passed to the terminal, but run function will resolve (async) / return (sync) null.

generate(src, dst, context)

generate a file specified by dst path by given template file src and context object

file1.tmp.js:

{
    author: '<%= AUTHOR %>'
}
generate('file1.tmp.js', 'file1.js', {AUTHOR: 'Pawel'});

will generate file1.js:

{
    author: 'Pawel'
}

ask(question)

Gather information from the user.

import { ask } from 'runjs'

export function prompt () {
  ask('Who are you?').then((name) => {
    console.log(`Hello ${name}!`) 
  })
}
$ run prompt
Who are you? Pawel
Hello Pawel!

Using Babel

If you have Babel and babel-register already installed, RunJS will pick up it automatically and use it for you runfile.js. If RunJS not finds babel-register it will fallback to pure node.

RunJS performs better with npm>=3.0 when using with Babel. It is because new version of npm handles modules loading much more effective.

If you have very specific location for your babel-register, you can define a path to it through config in your package.json (default path is ./node_modules/babel-register):

"runjs": {
    "babel-register": "./node_modules/some_package/node_modules/babel-register"
}

Scaling

When runfile.js gets large it is a good idea to extract some logic to external modules and import them back to runfile.js:

./tasks/css:

export function compile () {
  ...
}

./tasks/lint:

export function fix () {
  ...
}

./tasks/common:

export function serve () {
  ...
}

runfile.js:

import { run } from 'runjs'
import lint from './tasks/lint'
import css from './tasks/css'
import common from './tasks/common'

export default {
  css, // equals to css: css
  lint, // equals to lint: lint
  ...common,
  clean: () => {
    run('rm -rf node_modules') 
  },
  deploy: {
    'production': () => {
      
    },
    'staging': () => {
      
    }
  }
}
run css:compile
run lint:fix
run serve
run clean
run deploy:production
run staging:staging

You can notice a couple of approaches here but in general RunJS will treat object key as a namespace. It is also possible to bump tasks directly without the namespace by using ES7 object spread operator as with common tasks in the example above.

Documenting tasks

To display all available tasks from your runfile.js type run in your command line without any arguments:

$ run
Requiring babel-register...
Processing runfile...

Available tasks:
echo
testapi

Add doc property to your task to get additional description:

import { run } from 'runjs'

export function buildjs () {
  
}

buildjs.doc = 'Compile JavaScript files'
$ run
Requiring babel-register...
Processing runfile...

Available tasks:
buildjs - Compile JavaScript files