0
# CLI Interface
1
2
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.
3
4
## Capabilities
5
6
### CLI Commands
7
8
The Metalsmith CLI provides commands for building static sites from configuration files.
9
10
```bash { .api }
11
# Default build command
12
metalsmith [options]
13
14
# Explicit build command
15
metalsmith build [options]
16
```
17
18
### CLI Options
19
20
Configure CLI behavior with command-line options.
21
22
```bash { .api }
23
# Configuration file location (default: metalsmith.json)
24
metalsmith --config <path>
25
metalsmith -c <path>
26
27
# Set or override environment variables
28
metalsmith --env <setting...>
29
30
# Set or override DEBUG environment variable (shortcut)
31
metalsmith --debug <namespaces>
32
33
# Process files without writing to filesystem
34
metalsmith --dry-run
35
```
36
37
**Usage Examples:**
38
39
```bash
40
# Build from default metalsmith.json
41
metalsmith
42
43
# Build from custom config file
44
metalsmith --config lib/config.json
45
metalsmith -c build/metalsmith.js
46
47
# Override environment variables
48
metalsmith --env NODE_ENV=production TZ=Europe/London
49
50
# Enable debug output
51
metalsmith --debug @metalsmith/*
52
metalsmith --debug metalsmith-markdown,metalsmith-layouts
53
54
# Dry run (process without writing files)
55
metalsmith --dry-run
56
57
# Combined options
58
metalsmith --config site.json --env NODE_ENV=production --debug @metalsmith/*
59
```
60
61
### Configuration Files
62
63
The CLI supports both JSON and JavaScript configuration files.
64
65
**JSON Configuration (`metalsmith.json`):**
66
67
```json { .api }
68
{
69
"source": "src",
70
"destination": "build",
71
"clean": true,
72
"concurrency": 50,
73
"metadata": {
74
"sitename": "My Static Site",
75
"siteurl": "https://example.com/",
76
"description": "Site description"
77
},
78
"env": {
79
"NODE_ENV": "$NODE_ENV",
80
"DEBUG": false
81
},
82
"frontmatter": true,
83
"ignore": ["**/.DS_Store", "**/Thumbs.db"],
84
"plugins": [
85
{ "@metalsmith/drafts": true },
86
{ "@metalsmith/collections": { "posts": "posts/*.md" } },
87
{ "@metalsmith/markdown": { "gfm": true } },
88
{ "@metalsmith/permalinks": "posts/:title" },
89
{ "@metalsmith/layouts": { "pattern": "**/*.html" } }
90
]
91
}
92
```
93
94
**JavaScript Configuration (`metalsmith.js`):**
95
96
```javascript { .api }
97
import Metalsmith from 'metalsmith';
98
import drafts from '@metalsmith/drafts';
99
import collections from '@metalsmith/collections';
100
import markdown from '@metalsmith/markdown';
101
import permalinks from '@metalsmith/permalinks';
102
import layouts from '@metalsmith/layouts';
103
104
export default Metalsmith(__dirname)
105
.source('src')
106
.destination('build')
107
.clean(true)
108
.metadata({
109
sitename: 'My Static Site',
110
siteurl: 'https://example.com/',
111
description: 'Site description'
112
})
113
.use(drafts())
114
.use(collections({ posts: 'posts/*.md' }))
115
.use(markdown({ gfm: true }))
116
.use(permalinks('posts/:title'))
117
.use(layouts({ pattern: '**/*.html' }));
118
```
119
120
### Configuration File Resolution
121
122
The CLI resolves configuration files using the following priority:
123
124
1. File specified with `--config` option
125
2. `metalsmith.js` in current directory
126
3. `metalsmith.json` in current directory
127
128
**Multi-directory Support:**
129
130
```bash
131
# CLI adjusts working directory based on config file location
132
cd /project/subdirectory
133
metalsmith --config ../config/metalsmith.json
134
135
# Working directory becomes: /project/config/
136
# Relative paths in config resolve from config file location
137
```
138
139
### Environment Variable Expansion
140
141
JSON configuration files support environment variable expansion.
142
143
```json
144
{
145
"env": {
146
"NODE_ENV": "$NODE_ENV",
147
"API_URL": "$API_URL",
148
"DEBUG": "$DEBUG"
149
},
150
"metadata": {
151
"baseUrl": "$SITE_URL"
152
}
153
}
154
```
155
156
**Usage:**
157
158
```bash
159
# Set environment variables
160
export NODE_ENV=production
161
export SITE_URL=https://example.com
162
export DEBUG=@metalsmith/*
163
164
# Run build (variables will be expanded)
165
metalsmith
166
```
167
168
### Plugin Configuration
169
170
Configure plugins in JSON using object syntax.
171
172
```json { .api }
173
{
174
"plugins": [
175
// Plugin with boolean (use defaults)
176
{ "@metalsmith/drafts": true },
177
178
// Plugin with options object
179
{ "@metalsmith/markdown": {
180
"gfm": true,
181
"tables": true
182
}},
183
184
// Plugin with string option (shorthand)
185
{ "@metalsmith/permalinks": "posts/:title" },
186
187
// Local plugin (relative to config file)
188
{ "./plugins/custom-plugin": { "option": "value" } },
189
190
// Plugin array syntax (alternative)
191
{ "plugin-name": { "key": "value" } }
192
]
193
}
194
```
195
196
### CLI Environment Detection
197
198
The CLI automatically sets environment flags that plugins can detect.
199
200
```javascript { .api }
201
// Plugins can check if running via CLI
202
function cliAwarePlugin(files, metalsmith, done) {
203
const isCliMode = metalsmith.env('CLI');
204
205
if (isCliMode) {
206
console.log('Running via CLI');
207
// CLI-specific behavior
208
}
209
210
done();
211
}
212
```
213
214
### Error Handling and Output
215
216
The CLI provides formatted error messages and build status.
217
218
**Success Output:**
219
220
```bash
221
$ metalsmith
222
Metalsmith · reading configuration from: /path/to/metalsmith.json
223
Metalsmith · successfully built to: /path/to/build
224
```
225
226
**Error Output:**
227
228
```bash
229
$ metalsmith --config invalid.json
230
Metalsmith · it seems like invalid.json is malformed or unsupported.
231
Encountered error: Unexpected token '}' in JSON at position 45
232
233
$ metalsmith --config missing.json
234
Metalsmith · could not find a configuration file 'missing.json'.
235
236
$ metalsmith --config empty.js
237
Metalsmith · it seems like empty.js is empty. Make sure it exports a metalsmith config object.
238
239
$ metalsmith --config plugin-error.json
240
Metalsmith · failed to require plugin "non-existent-plugin".
241
242
$ metalsmith --config broken-plugin.json
243
Metalsmith · error using plugin "broken-plugin"...
244
TypeError: Cannot read property 'foo' of undefined
245
at plugin (/path/to/plugin.js:10:5)
246
```
247
248
### CLI Workflow Examples
249
250
Common CLI usage patterns and workflows.
251
252
**Development Workflow:**
253
254
```bash
255
# package.json scripts
256
{
257
"scripts": {
258
"build": "metalsmith",
259
"build:dev": "metalsmith --env NODE_ENV=development --debug @metalsmith/*",
260
"build:prod": "metalsmith --env NODE_ENV=production",
261
"preview": "metalsmith --dry-run",
262
"test": "metalsmith --config test/metalsmith.json --dry-run"
263
}
264
}
265
266
# Run development build
267
npm run build:dev
268
269
# Production build
270
npm run build:prod
271
272
# Preview without writing files
273
npm run preview
274
```
275
276
**Multi-environment Setup:**
277
278
```bash
279
# Directory structure:
280
# config/
281
# metalsmith.development.json
282
# metalsmith.production.json
283
# metalsmith.test.json
284
285
# Build for different environments
286
metalsmith --config config/metalsmith.development.json
287
metalsmith --config config/metalsmith.production.json --env NODE_ENV=production
288
metalsmith --config config/metalsmith.test.json --dry-run
289
```
290
291
**CI/CD Integration:**
292
293
```bash
294
#!/bin/bash
295
# build.sh
296
297
set -e # Exit on error
298
299
echo "Building site for environment: $NODE_ENV"
300
301
# Install dependencies
302
npm install
303
304
# Run build with environment-specific config
305
if [ "$NODE_ENV" = "production" ]; then
306
metalsmith --config config/production.json --env NODE_ENV=production
307
else
308
metalsmith --config config/development.json --env NODE_ENV=development --debug @metalsmith/*
309
fi
310
311
echo "Build completed successfully"
312
```
313
314
### Plugin Resolution
315
316
The CLI resolves plugins using Node.js module resolution:
317
318
1. **Local plugins**: `./path/to/plugin.js` (relative to config file)
319
2. **Node modules**: `@metalsmith/markdown` or `metalsmith-layouts`
320
3. **npm packages**: Any installed npm package
321
322
**Plugin Loading Examples:**
323
324
```json
325
{
326
"plugins": [
327
// Official scoped plugin
328
{ "@metalsmith/markdown": true },
329
330
// Community plugin
331
{ "metalsmith-layouts": { "pattern": "**/*.html" } },
332
333
// Local plugin file
334
{ "./lib/custom-plugin": { "enabled": true } },
335
336
// Local plugin directory (with index.js)
337
{ "./plugins/image-processor": {} }
338
]
339
}
340
```
341
342
### CLI Debugging
343
344
Debug the CLI itself and plugin loading process.
345
346
```bash
347
# Enable CLI debugging
348
DEBUG=metalsmith:cli metalsmith --debug @metalsmith/*
349
350
# Debug plugin resolution
351
DEBUG=metalsmith:plugins metalsmith
352
353
# Full debug output
354
DEBUG=* metalsmith --debug @metalsmith/*
355
```