Library / SDK
firebase/firebase-functions avatar
firebase/firebase-functions

The firebase-functions SDK turns Node handlers into Firebase triggers

Firebase SDK for Cloud Functions

1,067 stars233 forksTypeScriptMIT

At a glance

What is it?
firebase-functions is the Google maintained SDK that gives Cloud Functions for Firebase its trigger model, so an exported function and a path pattern become a deployed endpoint. The package carries both a v1 and a v2 API, ships the logger, params and lifecycle helpers as separate entry points.
Who is it for?
firebase-functions suits a team already on Firebase who wants event driven back end code, callable functions and database triggers without writing the deployment plumbing, and it suits a TypeScript project that wants typed params and a logger with an explicit compatibility layer.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the SDK actually does for you

Cloud Functions is described as a hosted, private and scalable Node.js environment where you can run JavaScript code. The firebase-functions package is the SDK for defining Cloud Functions for Firebase, and its job is to integrate the Firebase platform into that environment: you write code that responds to events and invokes functionality exposed by other Firebase features.

That phrasing points at the actual value. The hard part of a backend trigger system is not the handler body, it is the surrounding contract: how the runtime knows that this exported function should fire when a database path changes, how the function's region and memory and timeout are declared, how a secret is read, how the runtime passes the event data, and how the platform knows the function exists at deploy time. The SDK encodes all of that, so a handler is a normal exported function with a decorator-like call wrapped around it.

The audience is a developer who has chosen Firebase and wants the server side of that choice to be pleasant. The package is maintained by the Firebase Team at Google, is published under the MIT licence with a Google copyright from 2017, and its documentation lives with the rest of the Firebase documentation rather than in a separate site, with a quickstart, guides, a full API reference and a separate repository of samples.

The alternative, for context, is to not use the platform's trigger system at all and to run your own service that polls or subscribes to the database and talks to Firebase over the admin SDK. That gives you full control of the runtime, and it gives up the deployment model, the scaling behaviour and the credential plumbing that the SDK handles for you.

One package, two API generations

The repository layout records the package's history in directory names. At the top level there are src/, v1/ and v2/ directories, alongside spec/ for tests, mocha/ for the test harness, logger/ and lifecycle/ for those two helpers, docgen/ for documentation generation, protos/ for the protocol definitions, scripts/, integration_test/, and a .guides/ directory.

The manifest makes the structure concrete. The main entry point is lib/v2/index.js and the type definitions are lib/v2/index.d.ts, so an unqualified import gets you the second generation API. The v1 API is still shipped, at the ./v1 export path, with per-provider subpaths such as ./v1/analytics and ./v1/auth.

That coexistence is the single most important fact for anyone maintaining an existing codebase. A project can have functions written against v1 and functions written against v2 in the same repository, running side by side, and the difference is not cosmetic: the v2 API is a different set of shapes for triggers, for parameters and for the logger, and the two are not interchangeable. The exports map shows how deliberate this is, with separate import and require conditions for every entry point so that the package works in both module systems.

The version line in the manifest, 0.0.0-development, is also worth recognising: it is a placeholder that the release tooling replaces, which is the standard signal that a package publishes from the repository rather than from a hand edited version.

Writing a handler, from export to event

The usage example in the project documentation is the whole shape of the thing. A handler imports the trigger factory for the product you are reacting to, imports the logger, imports your own module, and exports a function whose name becomes the deployed function's name:

js
// functions/index.js
const { onValueCreated } = require("firebase-functions/database");
const logger = require("firebase-functions/logger");
const notifyUsers = require("./notify-users");

exports.newPost = onValueCreated({ ref: "/posts/{postId}" }, (event) => {
  logger.info("Received new post with ID:", event.params.postId);
  return notifyUsers(event.data.val());
});

Three things in that snippet carry the design.

The trigger is chosen by product and by path, so onValueCreated from the database module with a ref pattern of /posts/{postId} means this function runs when a value is created at a path matching that pattern. The braces in the path are the parameter syntax, which is the mechanism the platform uses to route the matching part of the path into the function.

The event carries both the matched parameters and the data. event.params.postId is the value the pattern captured, and event.data.val() is the payload at the time of the write. The parameter is typed, which is the practical benefit of the v2 API and the reason the params entry point exists as a separate export.

The logger is imported from its own module path rather than from the package root, and the manifest lists exactly two files as having side effects, the CommonJS and ESM builds of the logger's compat entry point. That declaration is there so a bundler does not tree-shake away the logger initialisation, and it tells you the logger has a compatibility layer that older code depends on.

Params, logger, lifecycle and a CLI entry point

The exports map is the best single view of what the package offers beyond the trigger functions. The subpaths are./lifecycle,./logger/compat,./logger,./params and./v1, plus the v1 provider subpaths, and each has a types entry, an import condition pointing at the ESM build and a require condition pointing at the CommonJS build.

The params module is the typed parameter layer. The README points to the API reference for the second generation Node API, and the parameters export exists so that a function can declare typed, validated inputs rather than reading untyped values out of a request. For a project that cares about type safety end to end, this is the piece that makes the handler body type check properly.

The logger module is the logging surface, with a separate compat subpath for code written against the older logging API. The lifecycle module covers the events around the function's own execution, which is what you use for a warm start or a shutdown hook rather than for a product event.

There is also a binary. The manifest declares a bin entry named firebase-functions pointing at lib/bin/firebase-functions.js, so the package ships a command line tool under the same name as the package itself.

The published files are the.guides directory, the lib output and the protos, and the package is side effect free apart from the two logger compat files noted above. Together with the TypeScript configuration files for the source, the declarations and the release build, and a tsdown config for the bundling step, this is a package organised for a dual module output with typed entry points, which is why it works inside both CommonJS and ESM projects.

The SDK is tested across unit, integration and generated docs

The repository is set up like a library that is published from source rather than edited in place, and the tooling shows it.

There is a spec/ directory and a mocha/ directory, with a .mocharc.yaml for the test runner configuration, and a separate integration_test/ directory for tests that exercise the deployed behaviour. The docgen/ directory holds the documentation generation, and protos/ holds the protocol definitions, which is what lets the SDK describe the platform's event payloads in a way that generates types.

The linting setup is unusual and worth noting, because it shows the project's history: there is an eslint.config.js for the current flat configuration and a tslint.json left in the tree from before the migration. Both are present, and a repository that has not finished removing the old linter is a small sign of a codebase in active maintenance rather than a rewrite.

The source is TypeScript, with a tsconfig.json for the project, a tsconfig.dts.json for the declaration build and a tsconfig.release.json for the release build, and the formatting is handled with a .prettierrc.js and a .prettierignore. A .guides/ directory is published with the package, which is how the quick start material reaches users through the package rather than only through the documentation site.

For a user of the SDK, none of this is visible. For someone who wants to read the implementation, or to contribute, it is a well organised repository where the trigger implementations, the provider modules and the parameter typing can be traced in a reasonable amount of time.

Rapid major releases, release candidates, and semantic versioning

The release pattern is the thing to watch. The recent tags are v7.3.3-rc.3 on 2026-09-11, v7.3.3-rc.4 on 2026-09-14 and v7.4.0 on 2026-09-15. So a release candidate was published, iterated on, and then promoted to a stable minor within a few days, and the major version has reached seven.

The semantic versioning convention matters here because the platform moves underneath the SDK. Firebase adds features, deprecates behaviour and changes the shape of some triggers, and a major version bump is how those changes reach users in a controlled way. The release candidate pattern exists for the same reason: a user on an older major version can pin it and upgrade when the next major is ready for their use, rather than being pushed onto a new API when a single provider changes.

The licence is MIT, with the copyright held by Google since 2017, and the LICENSE file is in the repository root. There is no vendor restriction on what you build with it beyond the usual attribution notice.

The repository is not archived and the last push was on 2026-10-15, so the SDK is actively maintained and the release train is fast. For a team pinning a version, that means your Firebase function dependencies are worth reviewing on a schedule rather than left to float, and that the difference between the v1 and v2 APIs is a migration you should schedule deliberately instead of discovering under pressure.

Editorial conclusion

firebase-functions suits a team already on Firebase who wants event driven back end code, callable functions and database triggers without writing the deployment plumbing, and it suits a TypeScript project that wants typed params and a logger with an explicit compatibility layer. It is the wrong choice if you want a runtime you control, since the package only makes sense inside the hosted Cloud Functions environment, and a poor match if you have existing v1 code, because the package keeps two API generations side by side and the newer entry points differ in shape. Before upgrading, check which generation your functions import, keep the logger compat entry point in mind for older code, and read the migration notes for your trigger type in the Firebase documentation before changing a deployed function.

Frequently asked questions

What does the firebase-functions package do?

It provides the SDK for defining Cloud Functions for Firebase, letting you write code that responds to events and invokes functionality exposed by other Firebase features, inside a hosted, private and scalable Node.js environment.

What is the difference between the v1 and v2 firebase-functions APIs?

The package ships both. The main entry point resolves to the second generation API at lib/v2/index.js, while the first generation is available at the ./v1 export path with per-provider subpaths. The v2 API has a different shape for triggers, parameters and logging, so code written against one is not interchangeable with the other.

How do I write a database trigger with firebase-functions?

Import the trigger factory for the product, such as onValueCreated from firebase-functions/database, pass a ref pattern with parameter placeholders like /posts/{postId}, and export the handler. The event gives you the matched parameters through event.params and the payload through event.data.

What licence is firebase-functions released under?

It is licensed under the MIT Licence, with the copyright held by Google since 2017 and the LICENSE file in the repository root. The package is maintained by the Firebase Team.

Official sources

  1. firebase/firebase-functions on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/firebase-firebase-functions.svg)](https://hysenlabs.com/projects/firebase-firebase-functions)

Was this useful?