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

roots-util

v0.2.0

Published

a utility for building roots extensions

Readme

Roots Util

npm tests dependencies Coverage Status

A utility that makes building roots extensions a little easier.

Why should you care?

Roots extensions, while quite powerful, can be complex to build, and difficult if you don't understand how roots core works thoroughly. Roots util provides utilities you can use to abstract common functionality if/when you need it.

Installation

npm install roots-util

Usage

Roots-util simply provides a bunch of utility functions, which are documented below. Before using any of them, you want to create an instance of roots-util, typically by passing through the roots object from the constructor as such:

RootsUtil = require 'roots-util'

class TestExtension
  constructor: (@roots) ->
    @util = new RootsUtil(@roots)

write(path, contents)

Writes a given relative path (starting at the roots public output directory) with the given content.

Example:

compile_hooks:
  write: => @util.write('testing.html', '<p>wow</p>')

This example will write to public/testing.html (or whatever the output directory was set to), and will also create any directories that were not already present. For example, if you wanted to write to public/foobar/testing.html, and the foobar directory didn't exist, it would create that directory rather than erroring out.

files(minimatch_str)

Given a minimatch string or array of minimatch strings, this function will grab all files in your roots project that match, excluding directories and files that were ignored by the roots config. Returns an array of vinyl-wrapped files.

Example:

constructor: (roots) ->
  util = new RootsUtil(roots)
  @css_files = util.files('assets/css/**').map((f) -> f.relative)

fs: ->
  detect: (f) => @css_files.indexOf(f.relative) > -1

This example pulls all non-ignored files in the css directory and tests whether we have a match in the fs.detect function. There are many other ways this can be used, just a quick example here.

output_path(path, ext)

Given the path to a source file in a roots project, produces the output path that it will be written to. Accepts an optional extension override (by default will return with the same file extension as the input). Returns a vinyl-wrapped file object.

Example:

compile_hooks: ->
  write: (ctx) =>
    out = @util.output_path(ctx.file.path).relative.split('.')
    out.splice(-1, 0, 'min')
    { path: out.join() }

In this example, we calculate the output path, add a .min extension, and pass that path in as the new path to be written. Again, contrived and this utility function can be used in many other ways, just a quick usage example.

with_extension(f, ext)

For use with the detect function, this is a helper that allows you to easily detect file extensions. Consider this a less powerful, but simpler version of the files helper. This function can accept a string or an array.

Example:

constructor: (@roots) ->
  @util = new RootsUtil(@roots)

fs: ->
  category: 'markdown'
  extract: true
  detect: (f) => @util.with_extension(f, ['md', 'markdown'])

Test Helpers

Roots-Util also includes a number of test helpers that might make testing your extensions a bit easier. The test helpers can be accessed as seen below:

path      = require 'path'
RootsUtil = require 'root-util'

# basic initialization
helpers = new RootsUtil.Helpers
# you can also initialize with a base fixtures directory, for example
helpers2 = new RootsUtil.Helpers(base: path.join(__dirname, 'fixtures'))

If you instantiate your helper with a base path, that base will be joined to any file path that's passed into any of the helper functions. Otherwise, you'll need to pass the full path. This helpers instance has a bunch of functions you can use to help out with your tests, documented below:

file.exists(path)

tests whether a file exists

file.doesnt_exist(path)

tests whether a file doesn't exist

file.has_content(path)

tests whether a file contains any content

file.is_empty(path)

tests whether a file contains no content

file.contains(path, string)

tests whether a file's contents contain a given string

file.contains_match(path, regex)

tests whether a file's content match a given regex

file.matches_file(path, path2)

tests whether a file's contents match a second file's contents

directory.is_directory(path)

tests whether a path is a directory

directory.exists(path)

tests whether a path is a directory and exists

directory.doesnt_exist(path)

tests whether a path does not exist

directory.has_contents(path)

tests whether a directory contains files

directory.is_empty(path)

tests whether a directory doesn't contain files

directory.contains_file(dirpath, filename)

tests whether a directory contains a file with a given filename

directory.matches_dir(path, path2)

tests whether a directory's contents match that of a second directory

project.compile(Roots, path)

returns a promise, compiles a roots project given the Roots class and a path for the project.

project.remove_folders(minimatchString)

given a minimatch string, removes all folders that match (good for removing public folders after tests have completed)

project.install_dependencies(baseDir, callback)

given a base directory (minimatch compatible), installs dependencies for any matches of baseDir/package.json then hits a callback

License & Contributing