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

pattern-manager

v0.1.3

Published

Tool for managing code patterns

Readme

Pattern manager

Tool for managing code patterns

Description

pattern-manager provides a way to manage a folder of code patterns and their generators, which can be application-specific or shared among projects.

It searches for a folder named .patterns in the current working directory or one of its ancestors. The .patterns folder can contain a number of pattern folders.

A pattern folder should contain a pattern.js, which exports a function to create the pattern, and any related template files. Each pattern is responsible to creating a copy of itself, for example: get options from the command-line or user inputs; copy files and folders; and compile templates.

To simplify the scaffolding process, the pattern generator function is provided with a set of utilities: inquirer, handlebars, shell, and chalk.

This tool is inspired by plop.

Install

Global

npm install pattern-manager -g

Local (for use in NPM scripts)

npm install pattern-manager -D

Run

pat

It searches for a .patterns folder, displays a list of patterns, and runs the selected pattern.

pat [pattern name] [...pattern options]

If a pattern name is specified, it runs that pattern.

Pattern

In the .patterns folder, there can be one or more pattern folders. These can be nested.

  • Each pattern is named after its folder
    • This includes the relative path, for example: react/state
  • Each pattern folder contains pattern.js and any template files
    • Any folder that doesn't have pattern.js will be ignored

The job of pattern.js is to create a copy of the pattern to its destination. It should export a function that receives a config object.

function pattern(config) {

  const { src, dest } = config

  // Create new pattern here

}

pattern.description = 'Desciption of pattern'

module.exports = pattern

If the function has a description property, it will be displayed when selecting patterns.

Config object

The pattern generator function is provided with a set of properties and utility methods.

  • src - Source path: the path of the pattern folder
  • dest - Destination path: current working folder
  • argv - Command line arguments via minimist
  • inquirer - Get different types of user input
  • handlebars - Compile templates
  • shell - Collection of shell commands
  • chalk - Colorful logging

Shortcuts

  • prompt - Shortcut for inquirer.prompt
  • compile - Shortcut for handlebars.compile
  • compileFile - Compile a template file and write to another file
    • Arguments: input file path, data object, output file path
  • error - Display an error message and exit
  • confirm - Ask for confirmation then return true/false
    • Arguments: a message and optional default value (default: true)
  • command - Shortcut for child_process.spawnSync with streaming output (stdio: inherit)
    • Arguments: command to run, array of arguments, spawnSync options
  • fileExists - Shortcut for fs.existsSync
  • readFile - Shortcut for fs.readFileSync with utf8 encoding
  • writeFile - Shortcut for fs.writeFileSync
  • writeJsonFile - Write object to human-readable JSON file
    • Arguments: file path, data object

Series of promises

If the pattern generator function returns an array of functions, they will be run as a series of promises.

Basic example

The following is a basic example of pattern.js.

  • Get user input
  • Compile a template and copy it to current folder
const path = require('path')

function pattern(config) {

  const { src, dest, prompt, compileFile } = config

  return [
    () => prompt([
      {
        name: 'message', default: 'Hello, world',
        message: 'Message to display'
      }
    ]),

    data => {

      const srcFile = path.join(src, 'example.js')
      const destFile = path.join(dest, 'example.js')

      compileFile(srcFile, data, destFile)

      console.log(`Wrote to ${destFile}`)
    }
  ]
}

pattern.description = 'Basic pattern'

module.exports = pattern

The example.js template:

console.log('{{message}}')

Advanced example

The following is an advanced example of pattern.js.

  • Take user input for the app name and description
  • If the destination exists, display error and quit
  • Copy all files in the pattern folder to its destination, using rsync
    • Ignore pattern.js itself, and everything in .gitignore
  • Replace name and description in package.json
  • Finally, it confirms to run git init and npm install

If --dry is passed in the command line, it will do a dry run without copying anything.

const path = require('path')

function pattern(config) {

  const {
    src, dest, argv, prompt, error, chalk,
    writeJsonFile, fileExists, quit
  } = config

  let name, destPath

  return [
    () => prompt([
      {
        name: 'name', default: 'app',
        message: 'Name of app',
        validate: function (value) {
          if (value) return true
          return 'App name is required'
        }
      },
      { name: 'description', default: '', message: 'Description' }
    ]),

    data => {

      name = data.name
      destPath = path.join(dest, name)
      const { description } = data

      if (fileExists(destPath)) {
        return error(`Destination "${name}" already exists`)
      }

      // ------------ Copy pattern ------------

      command('rsync', [
        '-vrlptz'+(argv.dry ? 'n' : ''), // -n for dry run
        '--delete',
        '--exclude', '.git',
        '--exclude', '/pattern.js', // Exclude this file
        '--filter', ':- .gitignore',
        '.', // Source
        destPath
      ], { cwd: __dirname })

      if (argv.dry) quit()

      // ------------ Search & replace ------------

      const packagePath = path.join(destPath, 'package.json')
      let packageData = require(packagePath)

      packageData.name = name
      packageData.description = description

      writeJsonFile(packagePath, packageData)
    },

    // ------------ Git init ------------

    () => confirm('Init .git repo?').then(confirmed => {
      if (!confirmed) return
      command('git', ['init'], { cwd: destPath })
    }),

    // ------------ npm install ------------

    () => confirm('Install NPM packages?').then(confirmed => {
      if (!confirmed) return
      command('npm', ['install'], { cwd: destPath })
    }),

    () => console.log(chalk.green(`Created "${name}"`))
  ]
}

pattern.description = 'Advanced pattern'

module.exports = pattern