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

@pixpilot/scaffoldfy

v0.47.2

Published

[![Documentation](https://img.shields.io/badge/docs-pixpilot.github.io/scaffoldfy-blue)](https://pixpilot.github.io/scaffoldfy/)

Readme

@pixpilot/scaffoldfy

Documentation

A flexible and powerful task automation utility for project setup, cleanup, and configuration.

Features

  • 🧩 Configuration Inheritance - Extend base configurations for code reuse
  • 🔍 Dry-Run Mode with Diff - Preview exact changes before applying
  • 🔌 Plugin System - Create custom task types and lifecycle hooks
  • 💬 Interactive Prompts - Collect user input with input, select, confirm, number, and password prompts
  • Variables - Define reusable values from static or executable sources without user interaction
  • �📦 JSON/TypeScript Config - Define tasks in JSON or TypeScript files
  • 🔗 Task Dependencies - Ensure tasks run in the correct order
  • Type-Safe - Full TypeScript support with JSON schema validation
  • 🎯 Template Variables - Use {{variable}} syntax for dynamic configuration
  • 📝 Handlebars Support - Advanced templating with conditionals, loops, and helpers
  • CLI & Programmatic - Use as a command-line tool or import as a library

Installation

npm install @pixpilot/scaffoldfy

Quick Start

CLI Usage

# Basic usage with default task file
scaffoldfy

# With custom tasks file
scaffoldfy --config ./config.json

# Preview changes (dry run)
scaffoldfy --dry-run

Or run without installing using npx:

# Basic usage with default task file
npx @pixpilot/scaffoldfy

# With custom tasks file
npx @pixpilot/scaffoldfy --config ./config.json

# Preview changes (dry run)
npx @pixpilot/scaffoldfy --dry-run

CLI Options

| Option | Description | | ----------------- | ------------------------------------------------------------------------------- | | --config <path> | Path to config file (JSON or TypeScript, default: ./scaffoldfy.json) | | --dry-run | Preview changes without applying them | | --no-validate | Skip schema validation of task configuration (validation is enabled by default) | | -h, --help | Show help message | | -v, --version | Show version |

Programmatic API

import { runWithTasks } from '@pixpilot/scaffoldfy';

await runWithTasks(tasks, {
  dryRun: false,
  force: false,
  configFilePath: './config.json',
});

Task Types

Built-in task types for common operations:

| Type | Purpose | | ----------------- | -------------------------------------------------- | | update-json | Update JSON files (supports nested properties) | | template | Create files from templates (simple or Handlebars) | | create | Create new files with optional content | | regex-replace | Find and replace with regex | | replace-in-file | Simple find and replace | | delete | Remove files/directories | | rename | Rename or move files | | move | Move files or directories | | copy | Copy files or directories | | append | Append content to existing files | | mkdir | Create directories | | git-init | Initialize git repository | | exec | Execute shell commands |

📖 Complete Task Types Reference →

Interactive Prompts

Collect user input at the root level - prompts are collected once before tasks run and available to all tasks:

{
  "prompts": [
    {
      "id": "projectName",
      "type": "input",
      "message": "What is your project name?",
      "required": true
    },
    {
      "id": "useTypeScript",
      "type": "confirm",
      "message": "Use TypeScript?",
      "default": true
    }
  ],
  "tasks": [
    {
      "id": "setup",
      "name": "Setup Project",
      "type": "update-json",
      "config": {
        "file": "package.json",
        "updates": {
          "name": "{{projectName}}"
        }
      }
    }
  ]
}

Supported prompt types: input, password, number, select, confirm

Root-level only: Prompts are defined at the root level, collected once upfront, and available to all tasks

💬 Full Prompts Guide → | 📋 Quick Reference →

Variables

Define reusable values without user interaction - automatically resolved from static values or executable commands:

{
  "variables": [
    {
      "id": "currentYear",
      "value": {
        "type": "exec",
        "value": "node -e \"console.log(new Date().getFullYear())\""
      }
    },
    {
      "id": "gitUserName",
      "value": {
        "type": "exec",
        "value": "git config user.name"
      }
    },
    {
      "id": "defaultLicense",
      "value": "MIT"
    }
  ],
  "tasks": [
    {
      "id": "update-license",
      "type": "template",
      "config": {
        "file": "LICENSE",
        "template": "Copyright {{currentYear}} {{gitUserName}}\n\nLicense: {{defaultLicense}}"
      }
    }
  ]
}

Use in tasks: Reference variables using {{variable}} syntax: {{currentYear}}, {{gitUserName}}, {{defaultLicense}}

Variable types: Static values, executable commands (with auto-parsing), or conditional expressions

📌 Complete Variables Guide →

Handlebars Templates

Create powerful file templates with Handlebars support. Files with .hbs extension automatically use Handlebars templating:

{
  "id": "readme-from-template",
  "name": "Generate README",
  "type": "template",
  "config": {
    "file": "README.md",
    "templateFile": "templates/readme.hbs"
  }
}

Automatic detection: Any template file ending in .hbs uses Handlebars. Other files use simple {{variable}} interpolation.

Template file (templates/readme.hbs):

#
{{projectName}}

{{#if description}}
  >
  {{description}}
{{else}}
  > A modern TypeScript project
{{/if}}

## Features

{{#each features}}
  -
  {{this}}
{{/each}}

{{#if author}}
  ## Author

  {{author}}
{{/if}}

Key features:

  • File-based only: Handlebars is only supported for external template files (.hbs extension)
  • Automatic detection: No configuration needed - just use .hbs files
  • Conditionals: {{#if}}, {{#unless}}, {{else}}
  • Loops: {{#each}}, {{#with}}
  • Comments: {{!-- This won't appear in output --}}

📝 Complete Handlebars Guide →

Config Inheritance

Extend base configs to promote code reuse:

{
  "extends": "./base-config.json",
  "tasks": [
    {
      "id": "custom-task",
      "name": "Custom Task",
      "description": "Project-specific setup",
      "required": true,
      "enabled": true,
      "type": "exec",
      "config": { "command": "echo 'Custom setup'" }
    }
  ]
}

You can extend multiple configs, override tasks by ID, and merge dependencies automatically.

🧬 Complete Inheritance Guide →

Dry-Run Mode with Diff Preview

Preview exactly what will change before applying:

scaffoldfy --config ./tasks.json --dry-run

See color-coded diffs for all file modifications, deletions, and additions.

🔍 Dry-Run Documentation →

Plugin System

Create custom task types for specialized operations:

import { createTaskPlugin, registerPlugin } from '@pixpilot/scaffoldfy';

const myPlugin = createTaskPlugin(
  'my-plugin',
  'custom-task',
  async (task, config, options) => {
    // Your custom logic here
  },
);

registerPlugin(myPlugin);

🔌 Complete Plugin Guide →

Task Dependencies

Control execution order:

{
  "tasks": [
    { "id": "clean", "type": "delete", "config": { "paths": ["dist"] } },
    {
      "id": "build",
      "dependencies": ["clean"],
      "type": "exec",
      "config": { "command": "pnpm build" }
    }
  ]
}

Example Configuration

Complete Example with Prompts and Variables

{
  "prompts": [
    {
      "id": "projectName",
      "type": "input",
      "message": "What is your project name?",
      "required": true
    },
    {
      "id": "author",
      "type": "input",
      "message": "Who is the author?",
      "default": {
        "type": "exec",
        "value": "git config user.name"
      }
    },
    {
      "id": "useTypeScript",
      "type": "confirm",
      "message": "Use TypeScript?",
      "default": true
    }
  ],
  "variables": [
    {
      "id": "currentYear",
      "value": {
        "type": "exec",
        "value": "node -e \"console.log(new Date().getFullYear())\""
      }
    },
    {
      "id": "license",
      "value": "MIT"
    }
  ],
  "tasks": [
    {
      "id": "update-package",
      "name": "Update package.json",
      "description": "Set project metadata",
      "type": "update-json",
      "config": {
        "file": "package.json",
        "updates": {
          "name": "{{projectName}}",
          "author": "{{author}}",
          "license": "{{license}}"
        }
      }
    },
    {
      "id": "create-readme",
      "name": "Create README",
      "description": "Generate README file",
      "type": "template",
      "config": {
        "file": "README.md",
        "template": "# {{projectName}}\n\nAuthor: {{author}}\nCopyright {{currentYear}}"
      }
    }
  ]
}

Simple Example

{
  "prompts": [
    {
      "id": "projectName",
      "type": "input",
      "message": "Project name?",
      "required": true
    }
  ],
  "tasks": [
    {
      "id": "update-package",
      "name": "Update package.json",
      "type": "update-json",
      "config": {
        "file": "package.json",
        "updates": {
          "name": "{{projectName}}"
        }
      }
    }
  ]
}

📁 More Examples →

Documentation

📚 Complete Documentation - Comprehensive guides and references

Quick Links

Resources

JSON Schema Support

Enable autocomplete and validation in your IDE:

{
  "$schema": "https://unpkg.com/@pixpilot/scaffoldfy/schema",
  "tasks": []
}

Contributing

Contributions are welcome! Please check out the Contributing Guide for guidelines.

Development

# Install dependencies
pnpm install

# Run tests
pnpm test

# Run tests in watch mode
pnpm test --watch

# Build
pnpm build

# Type check
pnpm typecheck

License

MIT