node package manager
We need your input. Help make JavaScript better: Take the 2017 JavaScript Ecosystem survey »



Awesome co-powered build system.

npm package

npm install -g gromjs


The goal of grom.js is to be a plugin-less build system that will allow to use any node module to process files without pain. Gives more control

Super simple

In gromfile.js:

var processor = require('files-processor')
var R = require('ramda')
module.exports.task = function* (){
  var filesSet = yield['path/to/files'])
  var mappedFilesSet =*(file){
    var newSource = processor(yield file.source())
    return file.clone(newSource, { ext: '.processed'})
  return yield this.write('path/to/dist', mappedFilesSet)

In terminal:

$ gromjs task

That's it. No special grom-whatever plugins, use whatever you want.


  • yield
    Returns ordered Set of Files

  • yield
    Returns events emitter, uses npm module watch and watch.createMonitor method

  • yield this.write(glob, Set)
    Accepts glob, Set of Files and writes everything in right place.

  • yield this.async(tasks)
    Accepts array of tasks and runs in asynchronously and independent to each other.

  • yield this.seq(tasks)
    Runs tasks one by one from left to right, every next one get result from previous.


Is a set of Files uniq by glob, have next methods:

  • elements()
    Returns Set's elements

  • isContains(file)
    Checks if file is in Set by file's glob

  • add(file)
    Returns new Set with all elements plus new one

  • remove(element)
    Returns new Set without single element

  • union(set)
    Returns new Set that is union of elements from both sets

  • intersection(set)
    Returns new Set that is intersection between sets

  • difference(set)
    Returns new Set that is difference between sets

  • filter(interator*)
    Returns new Set with filtered elements

  • sort(interator*)
    Returns new Set with sorted elements

  • reduce(interator*, accumulator)
    Returns reduced value

  • map(interator*)
    Returns new Set with mapped elements

  • forEach(interator*)
    Iterates over elements and returns current Set


  • path()
    Returns full path

  • glob()
    Returns glob

  • name()
    Returns name with extension

  • source()
    Generator, returns file's source code

  • clone([glob], [source])
    Creates new File, glob can be presented as hash with dir, name, ext fields which will be merged with parent file's path, path also can be just a string, if glob or source isn't provided, clone takes it from parent.


run tasks in sequence:

var filesProcessor = require('files-processor')
var read = function* (){
  return yield'/some/path/to/**.ext')
var processSet = function* (set){
  return* (file){
    var source = yield file.source()
    return file.clone(yield extProcessor(source), { ext: 'js' })
var write = function* (set){
  return yield this.write('/another/path', set)
module.exports.default = function* three(){
  yield this.seq([read, processSet, write])

watch files:

module.exports.default = function* three(){
  var monitor = yield'*.js')
  monitor.on('change', function* (Set){
    yield this.async(someTask)

compile less:

var less = require('less')
module.exports.compileLess = function* compileLess (){
  var lessFilesSet = yield'./code/**.less')
  var cssFilesSet = yield* (file){
    var lessContents = (yield file.source()).toString()
    var css = (yield less.render(lessContents, {})).css
    return file.clone(css, { ext: 'css' })
  return yield this.write('./dist', cssFilesSet)


$ gromjs <task-name>


  • Tasks logger
  • Tests
  • More examples


MIT © Dmitriy Kharchenko