Skip to content

Latest commit

 

History

History
212 lines (158 loc) · 9.5 KB

File metadata and controls

212 lines (158 loc) · 9.5 KB

@microsoft/spfx-template-api

Pre-release: APIs may change before the stable 1.0 release.

Programmatic API for loading, rendering, and writing SharePoint Framework (SPFx) project templates. This is the engine that powers @microsoft/spfx-cli. Use it directly when you need to integrate SPFx scaffolding into your own tooling.

npm install @microsoft/spfx-template-api

Requires Node.js >=22.14.0 <23.0.0 or >=24.12.0 <25.0.0


Quick start

import { Terminal, ConsoleTerminalProvider } from '@rushstack/terminal';
import {
  SPFxTemplateRepositoryManager,
  PublicGitHubRepositorySource,
  SPFxTemplateWriter,
  buildBuiltInContext
} from '@microsoft/spfx-template-api';

const terminal = new Terminal(new ConsoleTerminalProvider());

// 1. Load templates from GitHub
const manager = new SPFxTemplateRepositoryManager();
manager.addSource(new PublicGitHubRepositorySource({ repoUrl: 'https://github.com/SharePoint/spfx', terminal }));

const templates = await manager.getTemplatesAsync();
const template = templates.get('webpart-react');
if (!template) throw new Error('Template not found');

// 2. Build the render context from CLI inputs

const builtInContext = buildBuiltInContext({
  componentName: 'My Web Part',
  libraryName: 'my-spfx-library',
  spfxVersion: template.spfxVersion
});

// 3. Render to an in-memory file system
// String values are automatically wrapped with casing helpers (e.g. componentName.pascal)
const templateFs = await template.renderAsync(builtInContext);

// 4. Write files to disk (merges into existing SPFx solutions automatically)
const writer = new SPFxTemplateWriter();
await writer.writeAsync(templateFs, '/path/to/output');

Template sources

PublicGitHubRepositorySource

Fetches templates from a GitHub repository (github.com or GitHub Enterprise). Pin a specific SPFx version with an optional branch/tag ref. An optional token enables access to GitHub Enterprise instances or private repositories on github.com.

import { Terminal, ConsoleTerminalProvider } from '@rushstack/terminal';
import { PublicGitHubRepositorySource } from '@microsoft/spfx-template-api';

const terminal = new Terminal(new ConsoleTerminalProvider());

// Latest (defaults to the version/latest branch)
new PublicGitHubRepositorySource({ repoUrl: 'https://github.com/SharePoint/spfx', terminal });

// Specific version
new PublicGitHubRepositorySource({ repoUrl: 'https://github.com/SharePoint/spfx', branch: 'version/1.22', terminal });

// GitHub Enterprise with authentication
new PublicGitHubRepositorySource({
  repoUrl: 'https://github.mycompany.com/org/spfx-templates',
  terminal,
  token: process.env.GITHUB_TOKEN
});

LocalFileSystemRepositorySource

Loads templates from a local directory — useful for offline workflows, CI environments, or authoring custom templates.

import { LocalFileSystemRepositorySource } from '@microsoft/spfx-template-api';

new LocalFileSystemRepositorySource('./path/to/templates');

Combining sources

SPFxTemplateRepositoryManager merges templates from all registered sources. Later sources can override templates from earlier ones.

import { Terminal, ConsoleTerminalProvider } from '@rushstack/terminal';
import {
  SPFxTemplateRepositoryManager,
  PublicGitHubRepositorySource,
  LocalFileSystemRepositorySource
} from '@microsoft/spfx-template-api';

const terminal = new Terminal(new ConsoleTerminalProvider());
const manager = new SPFxTemplateRepositoryManager();
manager.addSource(new PublicGitHubRepositorySource({ repoUrl: 'https://github.com/SharePoint/spfx', terminal }));
manager.addSource(new LocalFileSystemRepositorySource('./my-custom-templates'));

const templates = await manager.getTemplatesAsync();

Writing to disk

SPFxTemplateWriter writes the in-memory TemplateOutput to the target directory. When scaffolding into an existing SPFx solution, it intelligently merges known config files (package.json, serve.json, etc.) via registered merge helpers. Unregistered text files that already exist on disk are preserved; binary files and new files are written directly.

const writer = new SPFxTemplateWriter();
await writer.writeAsync(templateFs, targetDir);

Merge helpers

The writer uses these helpers internally. You can also import them directly for custom merge scenarios:

Class Merges
JsonMergeHelper Abstract base for JSON/JSONC merge helpers (parse/serialize utilities)
PackageJsonMergeHelper package.json (preserves existing scripts and dependencies)
ConfigJsonMergeHelper SPFx config/ files
PackageSolutionJsonMergeHelper config/package-solution.json
ServeJsonMergeHelper config/serve.json

API reference

Export Description
ICasedString Interface exposing .camel, .pascal, .hyphen, .allCaps; auto-applied to all string context values during rendering
createCasedString Factory function that creates an ICasedString from a raw string
SPFxTemplateRepositoryManager Aggregates sources and returns a SPFxTemplateCollection
SPFxTemplateCollection Map<string, SPFxTemplate> of all loaded templates
SPFxTemplate Single template — exposes name, category, spfxVersion, and renderAsync()
ITemplateOutputEntry A single file entry (text or binary contents)
TemplateOutput In-memory file system implementation backed by a Map, returned by renderAsync()
PublicGitHubRepositorySource Loads templates from a GitHub repo (github.com or GHE, with optional auth token)
LocalFileSystemRepositorySource Loads templates from the local filesystem
BaseSPFxTemplateRepositorySource Base class for building custom template sources
SPFxRepositorySource Interface implemented by all source types
SPFxTemplateWriter Writes a TemplateOutput to disk with merge support
IWriteOptions Options for SPFxTemplateWriter.writeAsync() (includes optional log)
IMergeHelper Interface for implementing custom merge helpers
ServeJsonMergeHelper Merges config/serve.json (also available standalone)
SPFxScaffoldLog Append-only event log for recording scaffolding operations; serializes to JSONL
ISPFxScaffoldEventInput Input type for SPFxScaffoldLog.append() (timestamp is optional)
ISPFxScaffoldEvent Discriminated union of all scaffold event types
ISPFxScaffoldEventBase Base interface shared by every scaffold event (kind + timestamp)
ITemplateRenderedEvent Event recorded after a template is rendered
IPackageManagerSelectedEvent Event recorded when a package manager is chosen
IFileWriteEvent Event recorded for each file written during the write phase
FileWriteOutcome Union type: 'new' | 'merged' | 'preserved' | 'unchanged'
IPackageManagerInstallCompletedEvent Event recorded after the package-manager install exits
SCAFFOLD_LOG_FILENAME The well-known filename constant (.spfx-scaffold.jsonl)
SPFxTemplateCategory Union type of template categories: `'webpart'
SPFX_TEMPLATE_CATEGORIES Array of all valid category values (useful for validation/iteration)
ENGINE_VERSION Semver string identifying the installed engine version (matches package.json version)
buildBuiltInContext Computes the 10 built-in context variables from raw CLI inputs (UUIDs, solution name, badge URL, etc.)
ISPFxBuiltInContextInputs Input interface for buildBuiltInContext
ISPFxBuiltInContext Output interface — the 10 built-in variables every template receives
IBuildBuiltInContextOptions Options for buildBuiltInContext (e.g. ciMode)
BUILT_IN_PARAMETER_NAMES ReadonlySet of all built-in context variable names
ISPFxTemplateJson Shape of the template.json manifest (includes category, optional minimumEngineVersion)
SPFxTemplateDefinitionSchema Zod schema for validating a template.json (uses passthrough mode for forward compatibility)
SPFxTemplateJsonFile Typed wrapper around a parsed template.json file
SPFxTemplateRepositorySourceKind Union type of all built-in repository source kinds (`'local'
IPublicGitHubRepositorySourceOptions Options object for constructing a PublicGitHubRepositorySource
IRenderOptions Context object passed to template.renderAsync()

Scaffold event log

SPFxScaffoldLog records structured events during scaffolding. Pass it to writeAsync() to capture file-write outcomes, then serialize for debugging or analytics.

import { SPFxScaffoldLog, SPFxTemplateWriter, type IFileWriteEvent } from '@microsoft/spfx-template-api';

// Load existing log from disk (returns empty if file doesn't exist)
const log = await SPFxScaffoldLog.loadFromFolderAsync(targetDir);

// Check if this is an existing project
if (log.hasEntries) {
  console.log('Existing project detected');
}

// Record events during scaffolding
log.append({ kind: 'template-rendered', templateName: 'webpart-react', templateVersion: '1.0.0', spfxVersion: '1.22.0', context: { componentName: 'MyWebPart' }, cliVersion: '0.1.0' });

// Pass to writer to auto-record file-write events
const writer = new SPFxTemplateWriter();
await writer.writeAsync(templateFs, targetDir, { log });

// Persist back to disk
await log.saveToFolderAsync(targetDir);

License

MIT © Microsoft Corporation