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.
Module exports
Section titled “Module exports”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. |
EntryDescriptor
Section titled “EntryDescriptor”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). |
PluginHooks
Section titled “PluginHooks”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. |
PluginContext
Section titled “PluginContext”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. |
ExtForgePluginV1
Section titled “ExtForgePluginV1”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. |
ExtForgePluginLegacy
Section titled “ExtForgePluginLegacy”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. |
Example
Section titled “Example”import type { ExtForgePluginV1 } from 'extforge/plugins';
export function presetTailwind(): ExtForgePluginV1 { return { name: 'extforge:preset-tailwind', apiVersion: 1, setup({ hooks, logger }) { hooks.onBuildEntry((entry) => entry); }, };}