firebase-functions

The official SDK for writing and deploying Cloud Functions that respond to Firebase and Google Cloud events.

SDK
npm
v7.3.2
1,067stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
92/100Excellent
Development Activity92
Maintenance96
Community92
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
86/100Excellent
Architecture88
Code Quality90
Innovation85
Learning Curve80

firebase-functions is Google’s official SDK for building Cloud Functions for Firebase — a serverless Node.js runtime that lets you write event-driven backend code without provisioning servers. It exposes typed triggers for the platform’s own event surface: Firestore writes, Realtime Database changes, Authentication sign-ups, Cloud Storage uploads, Pub/Sub messages, scheduled cron jobs, and Firebase Alerts (Crashlytics, App Distribution, Performance, Billing), alongside HTTPS request and callable-RPC handlers built on Express.

The library ships two generations side by side: a legacy v1 API (firebase-functions/v1) that mirrors the original Cloud Functions trigger model, and the current v2 API built around Cloud Run-backed 2nd-gen infrastructure with per-function concurrency, memory, and region controls. Recent releases add first-class Genkit/Gemini AI action triggers and Firebase Data Connect (GraphQL) event support, reflecting the platform’s expansion beyond its original event types.

What You Get

  • Typed triggers for every native Firebase event source: Firestore, Realtime Database, Auth, Storage, Pub/Sub, Scheduler, Remote Config, Test Lab, and Firebase Alerts (Crashlytics, App Distribution, Performance, Billing)
  • HTTPS request and callable-RPC handlers with built-in CORS handling, App Check enforcement, and Express request/response types
  • A parameterized configuration system (params) for typed environment values and secrets resolved at deploy time instead of hardcoded config
  • v2 runtime options for concurrency, memory, min/max instances, VPC connectors, and per-region deployment on the Cloud Run-backed 2nd-gen platform
  • Genkit/Gemini AI action triggers and Firebase Data Connect (GraphQL) event support for newer platform surfaces
  • A structured logger module that integrates with Cloud Logging’s severity levels and structured metadata

Common Use Cases

  • Sending a push notification or email whenever a new Firestore document is created (e.g. new post, new order)
  • Enforcing server-side authorization and data validation on writes that a client SDK alone can’t be trusted to do
  • Running a nightly scheduled job to clean up stale data or roll up analytics via onSchedule
  • Exposing a callable HTTPS endpoint that a mobile or web client invokes directly through the Firebase client SDKs, with auth context automatically attached
  • Reacting to a new Firebase Auth user by provisioning their profile document or sending a welcome email
  • Processing images uploaded to Cloud Storage (resizing, generating thumbnails) via a Storage-triggered function

Under The Hood

Architecture The SDK is organized as three concentric layers: a shared core (src/common/) holding cross-generation primitives (options.ts, params.ts, encoding.ts, provider-agnostic HTTPS/Auth helpers under common/providers/), two parallel generation-specific trigger layers (src/v1/ mirroring the legacy Cloud Functions trigger model via cloud-functions.ts’s CloudFunction wrapper, and src/v2/ building HTTP/event handlers around a ManifestEndpoint produced by each provider file in src/v2/providers/), and a deploy-time bridge (src/runtime/loader.ts + src/runtime/manifest.ts) that the CLI entry point (src/bin/firebase-functions.ts) uses to load a user’s exported function stack and serialize it (stackToWire) into the JSON manifest the Firebase CLI actually deploys. This is a clean layered/modular design: trigger builders never talk to the deploy pipeline directly, only through the manifest data structure, so v1 and v2 triggers coexist and evolve independently while sharing options/params/encoding. The main architectural risk is the ManifestEndpoint interface itself — since every provider (Firestore, Auth, Pub/Sub, Scheduler, AI, Data Connect) ultimately serializes into it, a breaking change there ripples through every trigger file in both generations at once.

Tech Stack The package is written in TypeScript, targets Node.js >=18, and builds with tsdown plus tsc (per tsconfig.release.json) into dual CJS/ESM output (lib/ and lib/esm/) exposed through a large exports map in package.json. Its only true runtime dependencies are express (v5) and cors for the HTTPS/callable surface, plus protobufjs for encoding CloudEvent-style payloads; everything else (firebase-admin, genkit, graphql, @apollo/server) is a peer or dev dependency, kept optional via peerDependenciesMeta so consumers only pull in what they use — GraphQL/Apollo only if they touch Data Connect, for example. Linting runs through ESLint 9 with eslint-config-google and eslint-plugin-jsdoc, formatting through Prettier. The deployment target is Google Cloud Functions/Cloud Run, reached indirectly: this package never talks to GCP APIs itself, it only emits a manifest for the separate firebase-tools CLI to deploy.

Code Quality Tests live under spec/, mirroring src/ one-to-one across roughly fifty spec files (spec/v1/providers, spec/v2/providers, spec/common, spec/runtime, spec/lifecycle, spec/params), run via Mocha, Chai, Sinon, and chai-as-promised with nock for HTTP mocking. Error handling is explicit and typed — HttpsError in common/providers/https.ts models callable RPC errors with a FunctionsErrorCode union rather than throwing bare Errors, and withErrorHandler/withInit wrap handlers to convert unexpected exceptions into structured responses. Naming is consistent Google-style TypeScript (onValueCreated, onCall, onSchedule for behavior; ManifestEndpoint/TriggerAnnotation for data shapes). Type safety is strict, with nearly every exported symbol carrying a JSDoc block with @param/@internal/@alpha tags, and CI runs a full lint, test, and packaging matrix on every change, including a dedicated packaging test that guards the public exports map.

API Design The public API favors small, declarative one-liners over ceremony — onValueCreated({ ref: “/posts/{postId}” }, handler), onCall(handler), onSchedule(“every day 00:00”, handler) — with consistent on<Event><Verb> naming across every provider file, and typed options objects instead of positional arguments. Getting started requires almost no boilerplate: a single import plus a single exported function satisfies the Firebase CLI’s manifest loader. Documentation is unusually thorough for an SDK this size — nearly every exported type carries JSDoc consumed both by editor tooling and by the docgen/ API-Extractor pipeline that generates the official firebase.google.com reference pages, and the dual v1/v2 export paths let existing codebases upgrade trigger-by-trigger instead of in one breaking rewrite. The one friction point is the sheer size of the exports map, which requires knowing the right sub-path per provider.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search