npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@microsoft/spfx-template-api

v0.1.0-pre.3

Published

Library for generating SPFx solutions

Downloads

355

Readme

@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' | 'extension' | 'ace' | 'library' | | 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' | 'github') | | 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