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

@libria/scaffold

v0.2.0

Published

A pluggable CLI that transforms blank directories into production-ready codebases in seconds

Readme

@libria/scaffold

Forge your next project with lightning-fast scaffolding. A pluggable CLI that transforms blank directories into production-ready codebases in seconds.

Version License

✨ Features

  • Interactive CLI: Guided project creation with sensible defaults
  • Plugin System: Extensible architecture for custom templates
  • Configuration File: Register custom plugin directories via .lbscaffold
  • Dry Run Mode: Preview what will be generated before committing
  • Force Overwrite: Safely regenerate existing projects
  • Built-in Templates: TypeScript libraries and more included

Installation

npm install -g @libria/scaffold

Or use with npx:

npx lb-scaffold create

CLI Usage

Quick Start

Create a new project interactively:

lb-scaffold create

You'll be prompted for:

  • Template choice (e.g., ts-lib)
  • Project name
  • Additional template-specific options
  • Whether to initialize git and install dependencies

Non-Interactive Mode

Pass all options up-front for CI/CD or scripting:

lb-scaffold create -t ts-lib -n my-awesome-lib --dry-run

Options

| Option | Description | Default | |--------|-------------|---------| | -t, --template <name> | Template to use | (prompted) | | -n, --name <project-name> | Name of the new project folder | (prompted, required) | | --dry-run | Show what would be generated without writing files | false | | --force | Overwrite existing project folder if it exists | false | | -i, --interactive | Run in interactive mode | true |

Examples

Create a TypeScript library:

lb-scaffold create -t ts-lib -n my-utils

Preview generation without files:

lb-scaffold create -t ts-lib -n my-utils --dry-run

Force overwrite an existing project:

lb-scaffold create -t ts-lib -n my-utils --force

Included Templates

ts-lib

A modern TypeScript library template with:

  • ESLint + Prettier configuration
  • Vitest for testing
  • tsdown for fast builds
  • TypeScript path aliases
  • Package.json with proper exports
  • Comprehensive README and LICENSE

angular

A complete Angular application template using the official Angular CLI. Supports:

  • Angular versions: Latest, 20, 19, 18, 17, 16
  • Stylesheet formats: SCSS, CSS, Sass, Less
  • Optional routing module
  • Optional Server-Side Rendering (SSR)
  • Git initialization (optional)
  • Dependency installation (optional)
lb-scaffold create -t angular -n my-angular-app

Interactive prompts:

  • Angular version selection
  • Stylesheet format (SCSS recommended)
  • Add routing module?
  • Enable SSR?
  • Skip git initialization?
  • Skip npm install?

nestjs

A production-ready NestJS backend application using the official NestJS CLI. Includes:

  • TypeScript with strict mode (optional)
  • Package manager choice: npm, Yarn, or pnpm
  • Controller, Service, and Module structure
  • Unit test setup with Jest
  • E2E test configuration
  • Git initialization (optional)
  • Dependency installation (optional)
lb-scaffold create -t nestjs -n my-nest-api

Interactive prompts:

  • Package manager selection (npm, Yarn, pnpm)
  • Enable strict TypeScript mode?
  • Skip git initialization?
  • Skip package installation?

Configuration

The scaffold CLI supports a configuration file (.lbscaffold) that allows you to register custom plugin directories. This enables you to use your own templates alongside the built-in ones.

Config File Location

The CLI searches for .lbscaffold starting from the current directory and walking up the directory tree. This allows you to have project-specific or workspace-level configurations.

Config Commands

Initialize a new config file:

lb-scaffold config init

This creates a .lbscaffold file with a default plugin path:

{
  "plugins": ["./plugins/**"]
}

Add a custom plugin directory:

lb-scaffold config add ./my-templates/**

Remove a plugin directory:

lb-scaffold config remove ./my-templates/**

List all configured plugin patterns:

lb-scaffold config list

Show the full config file:

lb-scaffold config show

Config File Format

The .lbscaffold config file is a JSON file with the following structure:

{
  "plugins": [
    "./plugins/**",
    "./custom-templates/**",
    "/absolute/path/to/plugins/**"
  ]
}

The plugins array contains glob patterns pointing to directories containing template plugins. Paths can be:

  • Relative: Resolved relative to the config file location
  • Absolute: Used as-is

Plugin Override Behavior

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.

Example: Using Custom Templates

  1. Create a config file:

    lb-scaffold config init
  2. Add your custom templates directory:

    lb-scaffold config add ./my-company-templates/**
  3. Create a template plugin in that directory (see Creating Custom Template Plugins)

  4. Your template will now appear in the template selection:

    lb-scaffold create

Creating Custom Template Plugins

The scaffold CLI uses a plugin system powered by @libria/plugin-loader. Each template is a self-contained plugin.

Plugin Structure

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/

Step 1: Create plugin.json

{
    "name": "my-template",
    "version": "1.0.0",
    "type": "scaffold-template",
    "main": "./index.ts",
    "description": "My custom template"
}

Step 2: Define Types (types.ts)

import { ScaffoldTemplatePluginOptions } from "@libria/scaffold";

export type MyTemplateOptions = ScaffoldTemplatePluginOptions & {
    packageName: string;
    description: string;
    framework: 'react' | 'vue' | 'svelte';
};

Step 3: Implement the Plugin (my-template.ts)

import path from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs-extra';
import { input, confirm } from '@inquirer/prompts';
import { definePlugin } from '@libria/plugin-loader';
import { SCAFFOLD_TEMPLATE_PLUGIN_TYPE, ScaffoldTemplatePlugin } from '@libria/scaffold';
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
            const userOptions = await getInitialOptions(options);
            // Generate the project
            await generateProject(userOptions);
            // Post-processing
            await postProcess(userOptions);
        }
    }
);

async function getInitialOptions(
    options: ScaffoldTemplatePluginOptions
): Promise<MyTemplateOptions> {
    const packageName = await input({
        message: 'Package name:',
        default: options.name,
    });

    const description = await input({
        message: 'Description:',
    });

    const framework = await input({
        message: 'Framework (react/vue/svelte):',
        default: 'react',
    });

    return { packageName, description, framework, ...options };
}

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.
}

Step 4: Export the Plugin (index.ts)

export { default } from './my-template';
export * from './types';

Step 5: Create Template Files (files/)

Use placeholders that will be replaced:

package.json:

{
    "name": "{PACKAGE_NAME}",
    "description": "{DESCRIPTION}",
    "version": "1.0.0"
}

Step 6: Build the Templates

npm run build:templates

This compiles your template plugins to the dist/templates directory.

Development

# Install dependencies
npm install

# Build the project
npm run build

# Build templates
npm run build:templates

# Run tests
npm test

# Lint and format
npm run clean

License

MIT - see LICENSE file for details