CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-metalsmith

An extremely simple, pluggable static site generator for NodeJS

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

cli.mddocs/

CLI Interface

Command-line interface for running Metalsmith builds from configuration files with various options and environment variable support. The CLI provides a convenient way to run builds without writing JavaScript code.

Capabilities

CLI Commands

The Metalsmith CLI provides commands for building static sites from configuration files.

# Default build command
metalsmith [options]

# Explicit build command  
metalsmith build [options]

CLI Options

Configure CLI behavior with command-line options.

# Configuration file location (default: metalsmith.json)
metalsmith --config <path>
metalsmith -c <path>

# Set or override environment variables
metalsmith --env <setting...>

# Set or override DEBUG environment variable (shortcut)
metalsmith --debug <namespaces>

# Process files without writing to filesystem
metalsmith --dry-run

Usage Examples:

# Build from default metalsmith.json
metalsmith

# Build from custom config file
metalsmith --config lib/config.json
metalsmith -c build/metalsmith.js

# Override environment variables
metalsmith --env NODE_ENV=production TZ=Europe/London

# Enable debug output
metalsmith --debug @metalsmith/*
metalsmith --debug metalsmith-markdown,metalsmith-layouts

# Dry run (process without writing files)
metalsmith --dry-run

# Combined options
metalsmith --config site.json --env NODE_ENV=production --debug @metalsmith/*

Configuration Files

The CLI supports both JSON and JavaScript configuration files.

JSON Configuration (metalsmith.json):

{
  "source": "src",
  "destination": "build", 
  "clean": true,
  "concurrency": 50,
  "metadata": {
    "sitename": "My Static Site",
    "siteurl": "https://example.com/",
    "description": "Site description"
  },
  "env": {
    "NODE_ENV": "$NODE_ENV",
    "DEBUG": false
  },
  "frontmatter": true,
  "ignore": ["**/.DS_Store", "**/Thumbs.db"],
  "plugins": [
    { "@metalsmith/drafts": true },
    { "@metalsmith/collections": { "posts": "posts/*.md" } },
    { "@metalsmith/markdown": { "gfm": true } },
    { "@metalsmith/permalinks": "posts/:title" },
    { "@metalsmith/layouts": { "pattern": "**/*.html" } }
  ]
}

JavaScript Configuration (metalsmith.js):

import Metalsmith from 'metalsmith';
import drafts from '@metalsmith/drafts';
import collections from '@metalsmith/collections';
import markdown from '@metalsmith/markdown';
import permalinks from '@metalsmith/permalinks';
import layouts from '@metalsmith/layouts';

export default Metalsmith(__dirname)
  .source('src')
  .destination('build')
  .clean(true)
  .metadata({
    sitename: 'My Static Site',
    siteurl: 'https://example.com/',
    description: 'Site description'
  })
  .use(drafts())
  .use(collections({ posts: 'posts/*.md' }))
  .use(markdown({ gfm: true }))
  .use(permalinks('posts/:title'))
  .use(layouts({ pattern: '**/*.html' }));

Configuration File Resolution

The CLI resolves configuration files using the following priority:

  1. File specified with --config option
  2. metalsmith.js in current directory
  3. metalsmith.json in current directory

Multi-directory Support:

# CLI adjusts working directory based on config file location
cd /project/subdirectory
metalsmith --config ../config/metalsmith.json

# Working directory becomes: /project/config/
# Relative paths in config resolve from config file location

Environment Variable Expansion

JSON configuration files support environment variable expansion.

{
  "env": {
    "NODE_ENV": "$NODE_ENV",
    "API_URL": "$API_URL", 
    "DEBUG": "$DEBUG"
  },
  "metadata": {
    "baseUrl": "$SITE_URL"
  }
}

Usage:

# Set environment variables
export NODE_ENV=production
export SITE_URL=https://example.com
export DEBUG=@metalsmith/*

# Run build (variables will be expanded)
metalsmith

Plugin Configuration

Configure plugins in JSON using object syntax.

{
  "plugins": [
    // Plugin with boolean (use defaults)
    { "@metalsmith/drafts": true },
    
    // Plugin with options object
    { "@metalsmith/markdown": { 
      "gfm": true,
      "tables": true 
    }},
    
    // Plugin with string option (shorthand)
    { "@metalsmith/permalinks": "posts/:title" },
    
    // Local plugin (relative to config file)
    { "./plugins/custom-plugin": { "option": "value" } },
    
    // Plugin array syntax (alternative)
    { "plugin-name": { "key": "value" } }
  ]
}

CLI Environment Detection

The CLI automatically sets environment flags that plugins can detect.

// Plugins can check if running via CLI
function cliAwarePlugin(files, metalsmith, done) {
  const isCliMode = metalsmith.env('CLI');
  
  if (isCliMode) {
    console.log('Running via CLI');
    // CLI-specific behavior
  }
  
  done();
}

Error Handling and Output

The CLI provides formatted error messages and build status.

Success Output:

$ metalsmith
Metalsmith · reading configuration from: /path/to/metalsmith.json
Metalsmith · successfully built to: /path/to/build

Error Output:

$ metalsmith --config invalid.json
Metalsmith · it seems like invalid.json is malformed or unsupported. 
Encountered error: Unexpected token '}' in JSON at position 45

$ metalsmith --config missing.json  
Metalsmith · could not find a configuration file 'missing.json'.

$ metalsmith --config empty.js
Metalsmith · it seems like empty.js is empty. Make sure it exports a metalsmith config object.

$ metalsmith --config plugin-error.json
Metalsmith · failed to require plugin "non-existent-plugin".

$ metalsmith --config broken-plugin.json  
Metalsmith · error using plugin "broken-plugin"...
TypeError: Cannot read property 'foo' of undefined
    at plugin (/path/to/plugin.js:10:5)

CLI Workflow Examples

Common CLI usage patterns and workflows.

Development Workflow:

# package.json scripts
{
  "scripts": {
    "build": "metalsmith",
    "build:dev": "metalsmith --env NODE_ENV=development --debug @metalsmith/*",
    "build:prod": "metalsmith --env NODE_ENV=production", 
    "preview": "metalsmith --dry-run",
    "test": "metalsmith --config test/metalsmith.json --dry-run"
  }
}

# Run development build
npm run build:dev

# Production build
npm run build:prod

# Preview without writing files
npm run preview

Multi-environment Setup:

# Directory structure:
# config/
#   metalsmith.development.json
#   metalsmith.production.json  
#   metalsmith.test.json

# Build for different environments
metalsmith --config config/metalsmith.development.json
metalsmith --config config/metalsmith.production.json --env NODE_ENV=production
metalsmith --config config/metalsmith.test.json --dry-run

CI/CD Integration:

#!/bin/bash
# build.sh

set -e  # Exit on error

echo "Building site for environment: $NODE_ENV"

# Install dependencies
npm install

# Run build with environment-specific config
if [ "$NODE_ENV" = "production" ]; then
  metalsmith --config config/production.json --env NODE_ENV=production
else
  metalsmith --config config/development.json --env NODE_ENV=development --debug @metalsmith/*
fi

echo "Build completed successfully"

Plugin Resolution

The CLI resolves plugins using Node.js module resolution:

  1. Local plugins: ./path/to/plugin.js (relative to config file)
  2. Node modules: @metalsmith/markdown or metalsmith-layouts
  3. npm packages: Any installed npm package

Plugin Loading Examples:

{
  "plugins": [
    // Official scoped plugin
    { "@metalsmith/markdown": true },
    
    // Community plugin
    { "metalsmith-layouts": { "pattern": "**/*.html" } },
    
    // Local plugin file
    { "./lib/custom-plugin": { "enabled": true } },
    
    // Local plugin directory (with index.js)
    { "./plugins/image-processor": {} }
  ]
}

CLI Debugging

Debug the CLI itself and plugin loading process.

# Enable CLI debugging
DEBUG=metalsmith:cli metalsmith --debug @metalsmith/*

# Debug plugin resolution
DEBUG=metalsmith:plugins metalsmith

# Full debug output
DEBUG=* metalsmith --debug @metalsmith/*

docs

build-processing.md

cli.md

core-configuration.md

debugging.md

file-operations.md

frontmatter.md

index.md

plugin-system.md

utilities.md

tile.json