better-firebase-functions-esbuild

raw JSON →
7.1.1 verified Fri May 01 auth: no javascript

esbuild plugin for optimizing Firebase Cloud Functions builds. Version 7.1.1 is the latest stable, released April 2026, requiring Node >=20 and esbuild >=0.17.0. It provides per-function entry point generation with tree shaking by executing the BFF entry point in a discovery mode, automatically reusing runtime config (functionDirectoryPath, searchGlob, etc.) so no duplicate configuration is needed. Published weekly, it supports buildFunctions() as the recommended API, along with manual discovery helpers and a logging plugin. Differentiates from vanilla esbuild by automating the discovery of Firebase function files and maintaining the output directory structure matching the runtime layout.

error Error [ERR_REQUIRE_ESM]: require() of ES Module /path/to/node_modules/better-firebase-functions-esbuild/build/index.js from /path/to/your-script.js not supported.
cause Package is ESM-only since v7.0.0, but your project uses CommonJS require().
fix
Switch to import syntax and set "type": "module" in your package.json, or use dynamic import().
error TypeError: bffEsbuildPlugin is not a function
cause Incorrect import: default import attempted but bffEsbuildPlugin is a named export.
fix
Use import { bffEsbuildPlugin } from 'better-firebase-functions-esbuild'.
error Error: No functions discovered. Check your entry point exports functions via exportFunctions/exportFunctionsAsync.
cause Entry point does not call exportFunctions() or exportFunctionsAsync(), or the glob pattern finds no files.
fix
Ensure your entry point invokes exportFunctions({ ... }) with correct functionDirectoryPath and searchGlob.
breaking v6.0.0 dropped support for Node <14, upgraded all dependencies.
fix Upgrade Node to >=14 or use v5.0.0 if stuck on older Node.
breaking v7.0.0 switched to ESM-only; CommonJS require() no longer works.
fix Migrate your project to ESM (type: module in package.json) and use import syntax.
gotcha bffEsbuildPlugin() cannot add entry points dynamically; it only logs. Use buildFunctions() for actual bundling.
fix Use buildFunctions() instead of the plugin for per-function output.
gotcha If your entry point exports functions using exportFunctions(), you must provide the config at runtime; the plugin executes the entry point in discovery mode, so any external side effects may run twice.
fix Wrap side effects in guards that skip during discovery mode (check process.env.BFF_DISCOVERY).
npm install better-firebase-functions-esbuild
yarn add better-firebase-functions-esbuild
pnpm add better-firebase-functions-esbuild

Builds per-function bundles using the BFF entry point config (ESM, Node 20, TypeScript).

import { buildFunctions } from 'better-firebase-functions-esbuild';
import { resolve } from 'path';

// Ensure your entry point exports functions via exportFunctions/exportFunctionsAsync
await buildFunctions({
  entryPoint: resolve(__dirname, 'src/index.ts'),
  outdir: resolve(__dirname, 'dist'),
  target: 'node20',
  verbose: true,
});
// Output: dist/main.js and dist/functions/**/*.js mirroring runtime layout