Getting Started with scaffoldfy
This guide will help you get started with @pixpilot/scaffoldfy (formerly scaffoldfy) - a flexible and powerful task automation utility for project setup, cleanup, and configuration tasks.
Installation
Install the package using npm (or your preferred package manager):
npm install @pixpilot/scaffoldfy
Or install globally:
npm install -g @pixpilot/scaffoldfy
Using without Installation
You can also run scaffoldfy without installing it using npx:
npx @pixpilot/scaffoldfy --config ./setup/setup-tasks.json
Quick Start
Interactive Mode
The simplest way to use the tool - it will prompt you for configuration:
scaffoldfy
With Configuration File
Define your tasks in a JSON or TypeScript file and pass it to the CLI:
scaffoldfy --config ./tasks.json
Or with TypeScript:
scaffoldfy --config ./tasks.ts
Schema Validation
By default, all JSON task configuration files are validated against the JSON schema to catch configuration errors early. The schema validation ensures:
- Required fields are present
- Field types are correct
- Enum values are valid
- Configuration structure matches expected format
If validation fails, youâll see detailed error messages pointing to the issues:
scaffoldfy --config ./tasks.json
# Validating task configuration against schema...
# â Schema validation failed:
#
# The following validation errors were found:
#
# ⢠/tasks/0: Missing required property "type"
# ⢠/name: Value must match pattern: ^[a-z\d]+(?:-[a-z\d]+)*$
You can skip validation (not recommended) with the --no-validate flag:
scaffoldfy --config ./tasks.json --no-validate
Dry Run Mode
Preview what changes would be made without actually applying them:
scaffoldfy --config ./tasks.json --dry-run
Learn more: Dry Run Mode Documentation
Force Execution
Force execution even if checks fail:
scaffoldfy --force
Debug Mode
Enable debug logging to see detailed information about whatâs happening:
scaffoldfy --config ./tasks.json --debug
Debug mode provides verbose output including:
- Variable resolution details
- Task dependency resolution
- Plugin hook executions
- Configuration processing steps
- Detailed error messages
This is particularly useful for:
- Troubleshooting configuration issues
- Understanding task execution order
- Debugging configuration inheritance
- Verifying variable and prompt values
CLI Options
| Option | Description |
|---|---|
--config <path> |
Path to config file (JSON or TypeScript, default: ./config-tasks.json) |
--dry-run |
Preview changes without applying them |
--force |
Force execution even if checks fail |
--no-validate |
Skip schema validation of task configuration (validation is enabled by default) |
-h, --help |
Show help message |
-v, --version |
Show version |
Programmatic Usage
Using TypeScript Tasks
import { runWithTasks } from '@pixpilot/scaffoldfy';
import { tasks } from './my-tasks';
// Run with default options (interactive)
await runWithTasks(tasks);
// Run with dry-run enabled
await runWithTasks(tasks, { dryRun: true });
// Force execution
await runWithTasks(tasks, { force: true });
Loading Tasks from JSON
import fs from 'node:fs';
import { runWithTasks } from '@pixpilot/scaffoldfy';
const configFilePath = './config.json';
const tasksJson = JSON.parse(fs.readFileSync(configFilePath, 'utf-8'));
await runWithTasks(tasksJson.tasks);
Custom Task Example
import type { TaskDefinition } from '@pixpilot/scaffoldfy';
import { runWithTasks } from '@pixpilot/scaffoldfy';
const customTasks: TaskDefinition[] = [
{
id: 'setup-project',
name: 'Setup Project',
description: 'Initialize project with custom settings',
required: true,
enabled: true,
type: 'update-json',
config: {
file: 'package.json',
updates: {
name: '',
author: '',
version: '0.1.0',
},
},
},
{
id: 'create-readme',
name: 'Create README',
description: 'Generate project README',
required: true,
enabled: true,
type: 'write',
config: {
file: 'README.md',
template: `#
Created by
## Installation
\`\`\`sh
npm install
\`\`\`
`,
},
},
];
await runWithTasks(customTasks);
JSON Tasks Format
Basic Structure
{
"$schema": "https://unpkg.com/@pixpilot/scaffoldfy/schema",
"name": "my-config",
"description": "Optional description of what this configuration does",
"dependencies": ["optional-dependency-config"],
"tasks": [
{
"id": "unique-id",
"name": "Task Name",
"description": "What this task does",
"required": true,
"enabled": true,
"type": "update-json",
"config": {
"file": "package.json",
"updates": {
"name": ""
}
}
}
]
}
Note:
- The
namefield is required for all configurations. It must contain only lowercase letters, digits, and hyphens. It cannot start or end with a hyphen, or contain consecutive hyphens (e.g.,my-config,node-project-generator).- The
descriptionfield is optional but recommended for documentation.- The
dependenciesfield is optional and can be used to document configuration dependencies.- The
tasksarray is optional when using configuration inheritance. You can create configurations with onlypromptsand/orvariablesthat other configurations can extend. See Configuration Inheritance for details.- Task properties
description,required, andenabledare optional and default to"",true, andtruerespectively.
With Interactive Prompts
Add user prompts at the root level to collect custom input:
{
"name": "project-setup-with-prompts",
"description": "Configure project with interactive prompts",
"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": "Project Setup",
"description": "Configure project settings",
"required": true,
"enabled": true,
"type": "update-json",
"config": {
"file": "package.json",
"updates": {
"name": ""
}
}
}
]
}
Learn more: Interactive Prompts Guide
With Dependencies
Tasks can depend on other tasks to ensure correct execution order:
{
"name": "task-dependencies-example",
"description": "Demonstrates task execution order with dependencies",
"tasks": [
{
"id": "update-config",
"name": "Update Config",
"description": "Update configuration files",
"required": true,
"enabled": true,
"type": "update-json",
"config": {
"file": "config.json",
"updates": { "version": "1.0.0" }
}
},
{
"id": "install-deps",
"name": "Install Dependencies",
"description": "Install after config update",
"required": false,
"enabled": true,
"dependencies": ["update-config"],
"type": "exec",
"config": {
"command": "npm install"
}
}
]
}
Conditional Tasks
Use conditions to control task execution based on user input or configuration:
{
"id": "remove-examples",
"name": "remove-examples",
"description": "Delete example files if not needed",
"required": false,
"enabled": true,
"type": "delete",
"config": {
"condition": "removeExamples === true",
"paths": ["examples", "samples"]
}
}
Learn more: Advanced Features Guide
IDE Integration
VSCode
Add the schema reference to get autocomplete and validation in your JSON task files:
{
"$schema": "https://unpkg.com/@pixpilot/scaffoldfy/schema",
"tasks": []
}
WebStorm / IntelliJ IDEA
The JSON schema will be automatically detected if the $schema property is set in your JSON file.
Real-World Example
Hereâs a complete example that sets up a Node.js project:
{
"$schema": "https://unpkg.com/@pixpilot/scaffoldfy/schema",
"name": "node-project-setup",
"prompts": [
{
"id": "projectName",
"type": "input",
"message": "Project name?",
"required": true
},
{
"id": "description",
"type": "input",
"message": "Project description?"
},
{
"id": "license",
"type": "select",
"message": "Choose a license:",
"choices": ["MIT", "Apache-2.0", "GPL-3.0", "BSD-3-Clause"],
"default": "MIT"
}
],
"tasks": [
{
"id": "project-info",
"name": "Project Information",
"description": "Update package.json with project details",
"required": true,
"enabled": true,
"type": "update-json",
"config": {
"file": "package.json",
"updates": {
"name": "",
"description": "",
"license": "",
"author": ""
}
}
},
{
"id": "create-readme",
"name": "Create README",
"description": "Generate project README file",
"required": true,
"enabled": true,
"type": "write",
"config": {
"file": "README.md",
"template": "# \n\n\n\n## License\n\n"
}
},
{
"id": "git-init",
"name": "Initialize Git",
"description": "Set up git repository",
"required": false,
"enabled": true,
"dependencies": ["create-readme"],
"type": "git-init",
"config": {}
}
]
}
Best Practices
- Always use dry-run first - Test with
--dry-runbefore applying changes to see exactly what will happen - Keep tasks atomic - Each task should do one thing well and have a clear purpose
- Use dependencies wisely - Chain tasks that must run in a specific order
- Mark critical tasks as required - Essential tasks are
required: trueby default. Setrequired: falsefor optional tasks that shouldnât stop execution on failure - Document your tasks - Write clear names and descriptions for maintainability
- Version your task files - Keep task definitions in version control alongside your project
- Leverage the schema - Add
$schemato JSON files for IDE autocomplete and validation - Test with different inputs - Try various configuration values to ensure robustness
- Preview changes - Use dry-run mode to verify behavior before execution
Troubleshooting
âNo tasks definedâ error
Make sure youâre either:
- Passing
--configwith a valid JSON or TypeScript file path - Calling
runWithTasks()with a non-empty tasks array
âCircular dependency detectedâ error
Review your task dependencies - one or more tasks have circular references. Check the dependencies arrays in your tasks to ensure they form a directed acyclic graph (DAG).
âTask not foundâ error
A task lists a dependency that doesnât exist. Verify that all task IDs in dependencies arrays match existing task IDs exactly.
Configuration variables not replaced
Ensure youâre using the correct syntax: `` and that the variable:
- Is a built-in variable (like
projectName,author, etc.) - Or is defined in a root-level prompt with the matching
id
File not found errors
Check that:
- File paths are relative to the project root (where you run the command)
- Directories exist for files youâre trying to update
Next Steps
Now that youâre familiar with the basics, explore these topics:
- Task Types Reference - Learn about all built-in task types
- Interactive Prompts - Master user input collection
- Advanced Features - Conditional execution, global prompts, and Handlebars
- Configuration Inheritance - Compose and extend configurations
- Plugin System - Create custom task types
- Dry Run Mode - Preview changes with detailed diffs
Need Help?
- đ Browse the full documentation
- đ Report issues
- đŹ Ask questions in discussions