An extremely simple, pluggable static site generator for NodeJS
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Metalsmith is an extremely simple, pluggable static site generator for Node.js. It works by reading files from a source directory, running them through a series of plugins that manipulate the files, and then writing the results to a destination directory. All logic is handled by plugins, making it highly flexible and extensible.
npm install metalsmithimport Metalsmith from "metalsmith";For CommonJS:
const Metalsmith = require("metalsmith");import Metalsmith from "metalsmith";
import markdown from "@metalsmith/markdown";
import layouts from "@metalsmith/layouts";
const metalsmith = Metalsmith(__dirname)
.source("./src")
.destination("./build")
.clean(true)
.metadata({
sitename: "My Static Site",
siteurl: "https://example.com/"
})
.use(markdown())
.use(layouts({
pattern: "**/*.html"
}))
.build((err, files) => {
if (err) throw err;
console.log("Build finished!");
});Metalsmith follows a simple three-step process:
Key architectural components:
Essential methods for configuring Metalsmith instances including source/destination paths, build settings, and global metadata.
function Metalsmith(directory: string): Metalsmith;
// Configuration methods
directory(path?: string): string | Metalsmith;
source(path?: string): string | Metalsmith;
destination(path?: string): string | Metalsmith;
metadata(data?: object): object | Metalsmith;
clean(flag?: boolean): boolean | Metalsmith;
concurrency(max?: number): number | Metalsmith;Plugin management and execution system for extending Metalsmith functionality with custom transformations.
use(plugin: Plugin): Metalsmith;
type Plugin = (
files: Files,
metalsmith: Metalsmith,
callback: (error?: Error) => void
) => void | Promise<void>;Core build methods for processing files through the plugin pipeline and outputting results.
build(callback?: BuildCallback): Promise<Files> | void;
process(callback?: BuildCallback): Promise<Files> | void;
run(files: Files, plugins?: Plugin[], callback?: BuildCallback): Promise<Files> | void;
type BuildCallback = (error: Error | null, files: Files) => void;File reading and writing operations for handling individual files and file collections.
read(directory?: string, callback?: Callback): Promise<Files> | void;
readFile(filepath: string, callback?: (err: Error | null, file?: File) => void): Promise<File> | void;
write(files: Files, directory?: string, callback?: Callback): Promise<void> | void;
writeFile(filepath: string, data: File, callback?: (error: Error | null) => void): Promise<void> | void;Front-matter parsing and manipulation utilities for handling YAML/JSON metadata in files.
frontmatter(options?: boolean | GrayMatterOptions): boolean | Metalsmith;
// Available via metalsmith.matter property
matter.parse(contents: Buffer | string): File;
matter.stringify(file: File): string;
matter.options(options?: GrayMatterOptions): GrayMatterOptions | void;Utility methods for path resolution, file matching, environment variables, and debugging.
path(...paths: string[]): string;
match(patterns: string | string[], input?: string[], options?: object): string[];
env(name?: string | object, value?: any): any | Metalsmith;
ignore(files?: string | string[] | Function): string[] | Metalsmith;
watch(options?: boolean | string | string[] | object): boolean | object | Metalsmith;Debugging system with namespaced loggers and configurable output for development and troubleshooting.
debug(namespace: string): Debugger;
interface Debugger {
(message: string, ...args: any[]): void;
info(message: string, ...args: any[]): void;
warn(message: string, ...args: any[]): void;
error(message: string, ...args: any[]): void;
}Command-line interface for running Metalsmith builds from configuration files with various options and environment variable support.
metalsmith [options]
metalsmith build [options]import { Stats } from 'fs';
import { Mode } from 'stat-mode';
import { Debugger as DebugDebugger } from 'debug';
import { GrayMatterFile } from 'gray-matter';
import { WatchOptions } from 'chokidar';
interface Files {
[filepath: string]: File;
}
interface File<AdditionalProperties extends Record<string, unknown> = Record<string, unknown>> {
contents: Buffer;
stats?: Stats;
mode?: string;
} & AdditionalProperties
interface GrayMatterOptions {
language?: string;
excerpt?: boolean | ((file: GrayMatterFile<string>, options: GrayMatterOptions) => any);
excerpt_separator?: string;
delimiters?: string | string[];
engines?: {
[engine: string]: ((file: string) => any) | {
parse: (file: string) => any;
stringify?: (data: any) => string;
};
};
}
interface Debugger extends DebugDebugger {
info: DebugDebugger;
warn: DebugDebugger;
error: DebugDebugger;
}
type Plugin = (files: Files, metalsmith: Metalsmith, callback: DoneCallback) => void | Promise<void>;
type DoneCallback = (err?: Error) => void;
type Callback = (err: Error | null, files: Files) => void;
type Ignore = (path: string, stat: Stats) => boolean;