Creating a bluprint
A bluprint is any GitHub repo with a bluprint.config.ts at its root. Create one
with:
bluprint newThe config is authored with defineConfig, which gives you full type-checking
and autocomplete on every option:
import { defineConfig } from '@reuters-graphics/bluprint';
export default defineConfig({ name: 'My bluprint', bluprint: '^1.0.0', files: ['**/*'], ignores: [], actions: [],});Configuration options
Section titled “Configuration options”name (required)
Section titled “name (required)”The bluprint’s display name in the CLI. Either a string, or an object with a
hint shown beside it in the picker:
name: 'Svelte blog';name: { title: 'Svelte blog', hint: 'SvelteKit + Markdown posts',}files (required)
Section titled “files (required)”Globs for which files to scaffold, relative to the repo root. Use ['**/*'] for
everything.
files: ['src/**/*', 'package.json', 'README.md'];ignores (required)
Section titled “ignores (required)”Globs to exclude from files. (Files git already ignores are never scaffolded.)
ignores: ['**/*.test.ts', 'internal/**'];bluprint (optional)
Section titled “bluprint (optional)”A semver range for the CLI version your bluprint needs. The CLI warns on a mismatch and refuses to run if it’s too old — a safety net when your actions rely on newer features.
bluprint: '^1.0.0';actions (optional)
Section titled “actions (optional)”An array of actions that transform the scaffolded files, run in order. Actions are functions you import from the package:
import { defineConfig, prompt, render, execute,} from '@reuters-graphics/bluprint';
export default defineConfig({ name: 'My bluprint', files: ['**/*'], ignores: [], actions: [ prompt({ name: 'projectName', type: 'text', message: 'Project name?' }), render({ files: ['README.md', 'package.json'] }), execute('pnpm install', { silent: true }), ],});See the Actions guide.
parts (optional)
Section titled “parts (optional)”Named subsets of your bluprint a user can scaffold on their own — each with its
own files/ignores and optional actions:
parts: { config: { title: 'Config files', hint: 'Just the linters + tsconfig', files: ['.eslintrc.js', '.prettierrc', 'tsconfig.json'], ignores: [], },}See the Parts guide.
Typing the run context
Section titled “Typing the run context”Actions share a context that prompt
and run add values to. By default those custom values are typed unknown. Pass
a type argument to defineConfig describing them, and every action’s when,
run, and editor callback is typed against it — ctx.projectName autocompletes,
narrows, and catches typos:
import { defineConfig, prompt, render } from '@reuters-graphics/bluprint';
interface Context { projectName: string; includeCms: boolean;}
export default defineConfig<Context>({ name: 'Svelte blog', files: ['**/*'], ignores: [], actions: [ prompt({ name: 'projectName', type: 'text', message: 'Project name?' }), prompt({ name: 'includeCms', type: 'confirm', message: 'Add a CMS?' }), render({ files: ['svelte.config.js'], when: (ctx) => ctx.includeCms, // ✅ boolean, not unknown }), ],});The built-in DefaultContext keys
(year, dirname, …) are always present on top of what you declare.
Typing a run action
Section titled “Typing a run action”A run action’s ctx is typed too, and the
object it returns must match keys you’ve declared — so values it contributes are
type-safe in later actions. Declare those keys on your Context:
interface Context { projectName: string; slug: string; // contributed by the run action below}
export default defineConfig<Context>({ name: 'Svelte blog', files: ['**/*'], ignores: [], actions: [ prompt({ name: 'projectName', type: 'text', message: 'Project name?' }), run((ctx) => { // ctx.projectName is typed; the return must be a Partial<Context>. return { slug: ctx.projectName.toLowerCase().replace(/\s+/g, '-') }; }), // Later actions read ctx.slug as a string. render({ files: ['package.json'] }), ],});Publishing
Section titled “Publishing”There’s no publish step. Commit bluprint.config.ts, push to GitHub, and the
bluprint is ready — the CLI always pulls the latest from the repo.