Configuration
functional-examples is configured via a config file at your project root. This guide covers every config option, the two config formats, and how to use metadata schemas for validation.
Config Formats
TypeScript (recommended)
Create functional-examples.config.ts:
import { createJavaScriptPlugin } from '@functional-examples/javascript';
export default {
plugins: [createJavaScriptPlugin()],
scan: {
root: 'examples',
exclude: ['**/node_modules/**', '**/dist/**'],
},
};
TypeScript configs can instantiate plugins directly and benefit from type checking and IDE autocompletion.
JSON
Create functional-examples.config.json:
{
"$schema": "./.functional-examples/schema.json",
"scan": {
"include": ["snippets/**/*"],
"exclude": ["**/*.test.*", "**/*.spec.*"]
},
"pathMappings": [
{
"pattern": "**/legacy/**",
"extractor": "meta-yml"
}
],
"metadata": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the example"
},
"title": {
"type": "string",
"description": "Human-readable title"
},
"description": {
"type": "string",
"description": "What this example demonstrates"
},
"category": {
"type": "string",
"enum": ["tutorial", "recipe", "reference", "advanced"],
"description": "Example category for filtering"
},
"tags": {
"type": "array",
"items": { "type": "string" },
"description": "Tags for search and filtering"
}
},
"required": ["id", "title", "category"]
}
}
JSON configs are useful when you don't want a build step, work with non-JS tooling, or want machine-editable configuration. Plugins are auto-detected from your package.json dependencies.
Scan Options
scan.root
Base directory for scanning, relative to the config file. Defaults to the current directory.
scan: {
root: 'examples', // only scan under examples/
}
scan.include
Glob patterns for files to include. If omitted, all files under the root are candidates.
scan: {
include: ['snippets/**/*', 'tutorials/**/*'],
}
scan.exclude
Glob patterns for files to exclude. Always exclude node_modules and build artifacts:
scan: {
exclude: ['**/node_modules/**', '**/dist/**', '**/*.test.*'],
}
Path Mappings
When using multiple plugins, pathMappings route specific file patterns to specific extractors. This prevents conflicts when two extractors might both try to claim the same file.
pathMappings: [
{ pattern: 'src/**', extractor: 'javascript-extractor' },
{ pattern: 'tutorials/**', extractor: 'meta-yml' },
]
Each mapping has:
- pattern — a glob pattern matched against relative file paths
- extractor — the
extractorNameof the target extractor
Files matching a mapping are only sent to the specified extractor. Unmapped files are sent to all extractors.
Metadata Schema
You can enforce metadata standards using a JSON Schema in your config. Every scanned example's metadata is validated against it:
{
"$schema": "./.functional-examples/schema.json",
"scan": {
"include": ["src/**/*"],
"exclude": ["**/node_modules/**", "**/dist/**"]
},
"metadata": {
"type": "object",
"properties": {
"category": {
"type": "string",
"description": "Category for organizing examples"
},
"difficulty": {
"type": "string",
"enum": ["beginner", "intermediate", "advanced"],
"description": "Difficulty level"
}
},
"required": ["category", "difficulty"]
}
}
When an example's metadata doesn't match the schema, the scanner reports a validation error. Here's an example that passes validation:
// ---
// id: valid-example
// title: Valid Example
// description: This example has all required metadata fields
// category: tutorials
// difficulty: beginner
// ---
/**
* This example passes validation because it includes
* both `category` and `difficulty` fields.
*/
export function example() {
console.log('This example has valid metadata!');
}
And one that fails because it's missing required fields:
// ---
// id: missing-fields
// title: Missing Required Fields
// description: This example is missing category and difficulty
// ---
/**
* This example will produce validation errors because
* it's missing the required `category` and `difficulty` fields.
*
* Run `npx functional-examples scan` to see the validation errors.
*/
export function example() {
console.log('This example is missing required metadata!');
}
Region Config
functional-examples can extract #region / #endregion hunks from source files without any plugin. The region config block controls the marker keywords and which file extensions are recognised.
export default {
region: {
startTag: 'region', // default
endTag: 'endregion', // default
fileExtensionMap: {
// override or extend the built-in map
'.vue': [/\/\/\s*{token}\s+(\w+)/],
},
},
};
fileExtensionMap values can be RegExp literals (recommended in TypeScript configs) or pattern strings — the {token} placeholder is replaced with the configured startTag or endTag at scan time, and the first capturing group captures the region ID.
User-supplied entries are merged over the defaults; the defaults cover these extensions out of the box:
Config Resolution
When you call scan() or the CLI, functional-examples:
- Walks up from the current directory looking for
functional-examples.config.tsor.json - Loads the config (compiling TypeScript if needed)
- Resolves plugin references (for JSON configs, auto-detects from dependencies)
- Merges scan defaults with your overrides
- Returns a fully resolved config ready for scanning
You can also pass a config object directly to scanExamples() for programmatic use.