Micro-generator framework that makes it easy for an entire team to create files with a level of uniformity
npx @tessl/cli install tessl/npm-plop@4.0.0Plop is a micro-generator framework that makes it easy for development teams to create files with consistent patterns and structures. It combines interactive command-line prompts with Handlebars templates to automate the generation of boilerplate code, components, routes, controllers, and other repetitive file structures. By codifying file creation patterns, Plop helps maintain coding standards and best practices across teams.
npm install -g plop or npm install --save-dev plopFor CLI programmatic usage:
import { Plop, run } from "plop";For advanced programmatic usage (direct node-plop access):
import { nodePlop } from "plop";
// or
import nodePlop from "node-plop";For CommonJS:
const { Plop, run } = require("plop");
const { nodePlop } = require("plop");For CLI usage, no imports needed - use the plop command directly.
# Install globally
npm install -g plop
# Run plop (shows generator list)
plop
# Run specific generator
plop component
# Run generator with bypass data
plop component "MyComponent"import { Plop, run } from "plop";
import path from "node:path";
// Prepare and execute plop programmatically
Plop.prepare({
cwd: process.cwd(),
configPath: path.join(__dirname, 'plopfile.js'),
}, env => Plop.execute(env, run));Plop is built around several key components:
Full-featured CLI for running generators interactively or with bypass data. Includes help system, version information, and initialization commands.
// CLI entry point from bin/plop.js
import { Plop, run } from "../src/plop.js";
Plop.prepare(options, function (env) {
Plop.execute(env, run);
});Core execution functions for embedding Plop functionality in custom tools and workflows.
/**
* Main execution function for plop generators
* @param env - Environment object from Liftoff containing configuration
* @param _ - Unused parameter for compatibility
* @param passArgsBeforeDashes - Optional boolean to merge CLI and generator args
* @returns Promise resolving to plop instance
*/
async function run(env, _, passArgsBeforeDashes);
/**
* Liftoff instance configured for plop
*/
const Plop: Liftoff;
/**
* Ora spinner instance for progress indication
*/
const progressSpinner: ora.Ora;Comprehensive programmatic API for creating, configuring, and executing code generators through the node-plop package.
/**
* Create a new NodePlopAPI instance
* @param plopfilePath - Optional absolute path to plopfile
* @param plopCfg - Optional configuration object
* @returns Promise resolving to NodePlopAPI instance
*/
function nodePlop(plopfilePath?: string, plopCfg?: PlopCfg): Promise<NodePlopAPI>;
/**
* Register a new generator
* @param name - Unique generator name
* @param config - Generator configuration
* @returns PlopGenerator instance
*/
setGenerator(name: string, config: Partial<PlopGeneratorConfig>): PlopGenerator;
/**
* Execute generator prompts and actions
* @param bypassArr - Optional array to bypass prompts
* @returns Promise resolving to user answers
*/
runPrompts(bypassArr?: string[]): Promise<any>;Handlebars templating with built-in helpers, custom helpers, and partials for flexible file generation.
/**
* Register a custom Handlebars helper
* @param name - Helper name for use in templates
* @param fn - Helper function
*/
setHelper(name: string, fn: HelperFunction): void;
/**
* Register a Handlebars partial
* @param name - Partial name for use in templates
* @param str - Partial template string
*/
setPartial(name: string, str: string): void;
/**
* Render a Handlebars template string with data
* @param template - Handlebars template string
* @param data - Data object for template rendering
* @returns Rendered string
*/
renderString(template: string, data: any): string;Built-in file operations (add, addMany, modify, append) and support for custom actions.
/**
* Register a custom action type
* @param name - Action type name
* @param fn - Action function
*/
setActionType(name: string, fn: CustomActionFunction): void;
// Built-in action configuration interfaces
interface AddActionConfig extends ActionConfig {
type: "add";
path: string;
skipIfExists?: boolean;
} & TemplateStrOrFile;
interface ModifyActionConfig extends ActionConfig {
type: "modify";
path: string;
pattern: string | RegExp;
} & TemplateStrOrFile;User interface functions for displaying help, selecting generators, and creating initial plopfiles.
/**
* Display generator selection list to user
* @param plopList - Array of available generators
* @param message - Optional custom selection message
* @returns Promise resolving to selected generator name
*/
async function chooseOptionFromList(plopList, message);
/**
* Display help screen with usage information
*/
function displayHelpScreen();
/**
* Create initial plopfile.js or plopfile.ts
* @param force - Overwrite existing plopfile if present
* @param useTypescript - Generate TypeScript plopfile
*/
function createInitPlopfile(force, useTypescript);// Core configuration types
interface PlopCfg {
force?: boolean; // Force overwrite existing files
destBasePath?: string; // Base path for file operations
}
interface PlopGeneratorConfig {
description: string; // Human-readable description
prompts: Prompts; // Inquirer prompts or function
actions: Actions; // Actions to perform or function
}
// Generator and API interfaces
interface NodePlopAPI {
setGenerator(name: string, config: Partial<PlopGeneratorConfig>): PlopGenerator;
getGenerator(name: string): PlopGenerator;
getGeneratorList(): { name: string; description: string }[];
setHelper(name: string, fn: HelperFunction): void;
setPartial(name: string, str: string): void;
setActionType(name: string, fn: CustomActionFunction): void;
renderString(template: string, data: any): string;
}
interface PlopGenerator extends PlopGeneratorConfig {
runPrompts(bypassArr?: string[]): Promise<any>;
runActions(answers: Answers, hooks?: PlopActionHooks): Promise<{
changes: PlopActionHooksChanges[];
failures: PlopActionHooksFailures[];
}>;
}
// Action configuration types
interface ActionConfig {
type: string; // Action type name
force?: boolean; // Force overwrite
data?: object; // Additional template data
abortOnFail?: boolean; // Abort on action failure
skip?: Function; // Conditional skip function
}
interface AddActionConfig extends ActionConfig {
type: "add";
path: string;
skipIfExists?: boolean;
} & TemplateStrOrFile;
interface AddManyActionConfig extends ActionConfig {
type: "addMany";
destination: string;
base: string;
templateFiles: string | string[];
stripExtensions?: string[];
globOptions?: GlobOptions;
verbose?: boolean;
}
interface ModifyActionConfig extends ActionConfig {
type: "modify";
path: string;
pattern: string | RegExp;
} & TemplateStrOrFile;
interface AppendActionConfig extends ActionConfig {
type: "append";
path: string;
pattern: string | RegExp;
unique?: boolean;
separator?: string;
} & TemplateStrOrFile;
// Template and prompt types
interface TemplateStrOrFile {
template?: string; // Inline template string
templateFile?: string; // Path to template file
}
type Prompts = DynamicPromptsFunction | PromptQuestion[];
type Actions = DynamicActionsFunction | ActionType[];
type ActionType = AddActionConfig | AddManyActionConfig | ModifyActionConfig | AppendActionConfig | CustomActionConfig<string>;
type DynamicPromptsFunction = (inquirer: Inquirer) => Promise<Answers>;
type DynamicActionsFunction = (data?: Answers) => ActionType[];
type CustomActionFunction = (
answers: Answers,
config: CustomActionConfig<string>,
plopfileApi: NodePlopAPI,
) => Promise<string> | string;
// Hook system types
interface PlopActionHooks {
onComment?: (msg: string) => void;
onSuccess?: (change: PlopActionHooksChanges) => void;
onFailure?: (failure: PlopActionHooksFailures) => void;
}
interface PlopActionHooksChanges {
type: string;
path: string;
}
interface PlopActionHooksFailures {
type: string;
path: string;
error: string;
message: string;
}
// CLI and environment types
interface EnvironmentOptions {
cwd?: string;
preload?: string[];
configPath?: string;
completion?: any;
}
interface GeneratorInfo {
name: string;
description?: string;
}
// External library types
interface Liftoff {
prepare(options: PrepareOptions, callback: (env: LiftoffEnvironment) => void): void;
execute(env: LiftoffEnvironment, run: Function): any;
}
interface PrepareOptions {
cwd?: string;
preload?: string[];
configPath?: string;
completion?: any;
}
interface LiftoffEnvironment {
configPath: string;
cwd: string;
require: Function;
configName: string;
configBase: string;
configNameSearch: string[];
modulePackage: object;
modules: object;
}
interface Ora {
start(): Ora;
stop(): Ora;
succeed(text?: string): Ora;
fail(text?: string): Ora;
info(text?: string): Ora;
}