
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@libria/scaffold
Advanced tools
A pluggable CLI that transforms blank directories into production-ready codebases in seconds
Forge your next project with lightning-fast scaffolding. A pluggable CLI that transforms blank directories into production-ready codebases in seconds.
.lbscaffold.json~/.lbscaffold.json defaults with local per-key overridesnpm install -g @libria/scaffold
Or use with npx:
npx lb-scaffold new
Create a new project interactively:
lb-scaffold new
You'll be prompted to select a template, and then enter:
Pass all options up-front for CI/CD or scripting:
lb-scaffold new ts-lib my-awesome-lib --dry-run
| Option | Description | Default |
|---|---|---|
<name> | Name of the new project folder | (required) |
--dry-run | Show what would be generated without writing files | false |
--force | Overwrite existing project folder if it exists | false |
Template-specific options are available per template and will be shown in --help.
Create a TypeScript library:
lb-scaffold new ts-lib my-utils
Preview generation without files:
lb-scaffold new ts-lib my-utils --dry-run
Force overwrite an existing project:
lb-scaffold new ts-lib my-utils --force
Create a new Angular application with specific options:
lb-scaffold new angular my-app --version 20 --style scss --routing --ssr
A modern TypeScript library template with:
A complete Angular application template using the official Angular CLI. Supports:
lb-scaffold new angular my-angular-app
Interactive prompts:
A production-ready NestJS backend application using the official NestJS CLI. Includes:
lb-scaffold new nestjs my-nest-api
Interactive prompts:
A Next.js application template using the official create-next-app. Supports:
lb-scaffold new nextjs my-next-app
Interactive prompts:
A TypeScript workspace (monorepo) template using npm workspaces and TypeScript project references. Provides two subcommands:
init — Create a new workspace with shared tsconfig, package.json workspaces, and git setupadd — Add projects into an existing workspace using other templates (ts-lib, angular, nestjs, nextjs)Automatically manages workspace package.json entries, TypeScript project references, and tsconfig inheritance.
# Create a new workspace
lb-scaffold new ts-workspace my-monorepo
# Add a project into the workspace
lb-scaffold new ts-workspace my-lib --workspace ./my-monorepo --template ts-lib
Interactive prompts (init):
Interactive prompts (add):
The scaffold CLI supports a configuration file (.lbscaffold.json) that allows you to register custom plugin directories and npm packages. This enables you to use your own templates alongside the built-in ones.
The CLI supports two config file locations:
~/.lbscaffold.json — provides machine-wide defaults.lbscaffold.json found by searching up from the current directoryWhen both exist, local keys override global keys on a per-key basis. For example, if the local config defines plugins, it fully replaces the global plugins; keys not present locally fall through to the global config.
Initialize a new config file in the current directory:
lb-scaffold config init
Initialize the global config file:
lb-scaffold config init -g
This creates a .lbscaffold.json file with a default plugin path:
{
"plugins": ["./plugins/**"],
"packages": []
}
Add a custom plugin directory:
lb-scaffold config add ./my-templates/**
# Add to global config
lb-scaffold config add ./my-templates/** -g
Remove a plugin directory:
lb-scaffold config remove ./my-templates/**
List all configured plugin patterns (shows merged config with source indicators):
lb-scaffold config list
# Show only global config
lb-scaffold config list -g
Show the full config file:
lb-scaffold config show
# Show only global config
lb-scaffold config show -g
All config subcommands accept -g / --global to target the global config (~/.lbscaffold.json) instead of the local one.
The .lbscaffold.json config file is a JSON file with the following structure:
{
"plugins": [
"./plugins/**",
"./custom-templates/**",
"/absolute/path/to/plugins/**"
],
"packages": [
"@libria/scaffold-plugin-angular",
"@libria/scaffold-plugin-nestjs"
]
}
The plugins array contains glob patterns pointing to directories containing template plugins. Paths can be:
The packages array contains npm package names that provide scaffold template plugins. These packages will be loaded via node_modules.
Add an npm package as a plugin source:
lb-scaffold config add-package @your-org/scaffold-plugin-my-template
Remove an npm package:
lb-scaffold config remove-package @your-org/scaffold-plugin-my-template
List all configured npm packages:
lb-scaffold config list-packages
When a user plugin has the same name as a built-in plugin, the user plugin takes precedence. This allows you to customize or replace built-in templates.
Create a config file:
lb-scaffold config init
Add your custom templates directory:
lb-scaffold config add ./my-company-templates/**
Create a template plugin in that directory (see Creating Custom Template Plugins)
Your template will now appear in the template selection:
lb-scaffold new
The scaffold CLI uses a plugin system powered by @libria/plugin-loader. Each template is a self-contained plugin.
templates/
└── my-template/
├── plugin.json # Plugin metadata
├── index.ts # Plugin entry point
├── types.ts # TypeScript types
├── my-template.ts # Implementation
└── files/ # Template files
├── package.json
├── tsconfig.json
└── src/
{
"name": "my-template",
"version": "1.0.0",
"type": "scaffold-template",
"main": "./index.ts",
"description": "My custom template"
}
import {
ScaffoldTemplatePluginOptions,
ScaffoldTemplatePluginOption,
} from "@libria/scaffold-core";
export type MyTemplateOptions = ScaffoldTemplatePluginOptions & {
packageName: string;
description: string;
framework: 'react' | 'vue' | 'svelte';
};
import path from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs-extra';
import { definePlugin } from '@libria/plugin-loader';
import { SCAFFOLD_TEMPLATE_PLUGIN_TYPE, ScaffoldTemplatePlugin } from '@libria/scaffold-core';
import { MyTemplateOptions } from './types';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const FILES_DIR = path.resolve(__dirname, 'files');
export default definePlugin<ScaffoldTemplatePlugin>(
SCAFFOLD_TEMPLATE_PLUGIN_TYPE,
'my-template',
{
argument: 'my-template',
async execute(options: ScaffoldTemplatePluginOptions): Promise<void> {
// Collect user input (via getOptions - see ScaffoldTemplatePlugin)
const userOptions = options as MyTemplateOptions;
// Generate the project
await generateProject(userOptions);
// Post-processing
await postProcess(userOptions);
},
async getOptions(options: ScaffoldTemplatePluginOptions): Promise<Record<string, ScaffoldTemplatePluginOption>> {
return {
packageName: {
flags: '-p, --package-name <name>',
description: 'Package name',
defaultValue: options.name,
},
description: {
flags: '-d, --description <text>',
description: 'Project description',
},
framework: {
flags: '-f, --framework <name>',
description: 'Framework',
defaultValue: 'react',
choices: ['react', 'vue', 'svelte'],
},
};
},
}
);
async function generateProject(options: MyTemplateOptions): Promise<void> {
const { name, dryRun, force } = options;
const targetDir = path.resolve(process.cwd(), name);
// Handle existing directory
if (await fs.pathExists(targetDir)) {
if (!force) {
console.error(`Directory '${name}' already exists. Use --force to overwrite.`);
process.exit(1);
}
if (!dryRun) {
await fs.remove(targetDir);
}
}
// Create and copy files
if (!dryRun) {
await fs.ensureDir(targetDir);
await fs.copy(FILES_DIR, targetDir);
// Replace placeholders
await replacePlaceholders(targetDir, options);
}
console.log(`Project '${name}' created successfully!`);
}
async function replacePlaceholders(
targetDir: string,
options: MyTemplateOptions
): Promise<void> {
// Replace {PACKAGE_NAME}, {DESCRIPTION}, etc. in files
}
async function postProcess(options: MyTemplateOptions): Promise<void> {
// Git init, npm install, etc.
}
export { default } from './my-template';
export * from './types';
Use placeholders that will be replaced:
package.json:
{
"name": "{PACKAGE_NAME}",
"description": "{DESCRIPTION}",
"version": "1.0.0"
}
npm run build:templates
This compiles your template plugins to the dist/templates directory.
This package is part of the LibriaForge Scaffold monorepo. From the repo root:
# Install all dependencies
npm install
# Build all packages
npm run build
# Run all tests
npm run test
Or work on the CLI package directly:
cd cli
npm run build
npm test
npm run clean
MIT - see LICENSE file for details
FAQs
A pluggable CLI that transforms blank directories into production-ready codebases in seconds
We found that @libria/scaffold demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.