Skip to content

Plugin API

ExtForge plugins are TypeScript objects implementing ExtForgePluginV1. They register hooks during setup() and the runner fires those hooks at well-defined points in the build.

extforge/plugins exports:

Export Kind Notes
presetReact function The first-party React preset. See presetReact.
PresetReactOptions type Options accepted by presetReact().
ExtForgePluginV1 interface The modern plugin shape (apiVersion: 1). Documented below.
ExtForgePluginLegacy interface The pre-v1 plugin shape, still accepted. Documented below.
ExtForgePlugin type Union of `ExtForgePluginV1
PluginContext, PluginHooks, EntryDescriptor interfaces The context, hook registry, and entry descriptor. Documented below.
ManifestObject type Record<string, unknown> — the untyped manifest passed to onManifestTransform.
PluginRunner class The engine that loads plugins and fires hooks. Exported for advanced/test use; most plugins never touch it.

Describes a single entry point to be bundled by esbuild.

Member Type Description
name string Logical name used to derive the output filename.
file string Absolute or root-relative path to the entry source file.
format "esm" | "iife" Output bundle format.
esbuildOptions? Record<string, unknown> | undefined Extra esbuild options merged into this entry’s build.
isContentScript? boolean | undefined Whether this entry is a content script (affects IIFE wrapping).

Hook registration methods available inside a plugin’s setup() call.

Member Type Description
onConfigResolved (fn: (config: ExtForgeConfig) => void | Promise<void>) => void Called once after config resolution, before any build.
onManifestTransform (fn: (manifest: ManifestObject, browser: Browser) => ManifestObject | Promise<ManifestObject>) => void Called for each browser after the manifest is assembled, allowing mutation.
onBuildStart (fn: (info: { browser: Browser; dev: boolean; }) => void | Promise<void>) => void Called at the start of each browser build.
onBuildEntry (fn: (entry: EntryDescriptor) => EntryDescriptor | void | Promise<EntryDescriptor | void>) => void Called once per entry point, allowing plugins to mutate or replace the descriptor.
onBuildEnd (fn: (result: BuildResult) => void | Promise<void>) => void Called after all entries for a browser have been bundled.
onCssTransform (fn: (ctx: CssTransformContext) => string | void | Promise<string | void>) => void Called for each emitted stylesheet after the base CSS processor runs,
allowing plugins to transform CSS (Sass, Lightning CSS, autoprefixing,
a design-system pass…). Hooks chain: each receives the previous step’s
output as ctx.code. Return the transformed CSS, or nothing to skip.
onDevReload (fn: (event: HMRUpdate) => void | Promise<void>) => void Called in dev mode each time the HMR server dispatches a reload event.

Runtime context injected into every plugin’s setup() function.

Member Type Description
config ExtForgeConfig The resolved ExtForge configuration for the current build.
paths { readonly root: string; readonly src: string; readonly dist: string; } Resolved absolute paths for the project root, source, and output directories.
logger Logger Logger instance scoped to the plugin runner.
hooks PluginHooks Hook registration object for this plugin’s subscriptions.
addEntry (entry: EntryDescriptor) => void Adds a synthetic entry point to the build without touching the config.
emitFile (rel: string, contents: string | Uint8Array<ArrayBufferLike>) => void Writes a file to the output directory at the given relative path.

A plugin written against the v1 ExtForge plugin API.

Member Type Description
name string Unique-ish identifier; surfaces in logs and error messages.
apiVersion 1 Required discriminator; routes the runner to the modern API.
setup (ctx: PluginContext) => void | Promise<void> Called once after config resolution. Plugins register hooks here.

Thin legacy plugin shape accepted for backwards compatibility.

Member Type Description
name string Unique-ish identifier; surfaces in logs and error messages.
setup? ((config: ExtForgeConfig) => void | Promise<void>) | undefined Optional hook called once with the resolved config.
buildStart? (() => void | Promise<void>) | undefined Optional hook called at the start of each build.
buildEnd? ((result: unknown) => void | Promise<void>) | undefined Optional hook called after each build completes.
import type { ExtForgePluginV1 } from 'extforge/plugins';
export function presetTailwind(): ExtForgePluginV1 {
return {
name: 'extforge:preset-tailwind',
apiVersion: 1,
setup({ hooks, logger }) {
hooks.onBuildEntry((entry) => entry);
},
};
}