> Documentation index: https://firebase.google.com/docs/extensions/llms.txt

This guide shows you how to migrate your extensions from the deprecated
[Firebase Extensions](https://firebase.google.com/docs/extensions.md.txt) environment to a function kit that
you can install and deploy in your own [Cloud Functions](https://firebase.google.com/docs/functions.md.txt)
for Firebase (2nd gen) codebase.

Firebase Extensions managed all aspects of creating, updating, and removing
extensions. Function kits package the capabilities of extensions as typical 2nd
gen Cloud Functions for Firebase. Because function kits are standard
Cloud Functions, you create, update, delete, and troubleshoot them using
the Firebase CLI within your Firebase project. This guide prepares
you to manage your functions now and adopt updates as they become available.

Throughout this guide, the [Stream Cloud Firestore to BigQuery](https://extensions.dev/extensions/firebase/firestore-bigquery-export)
extension (`firestore-bigquery-export`) is used as an example that shows you the
commands and command output for each step of the migration.

> [!WARNING]
> **Warning:** This migration guide has steps that fetch your existing extension configuration to configure the replacement function kit identically. This won't be possible after March 31, 2027. We strongly recommend you migrate before March 31, 2027. If you aren't going to migrate before then, you can preemptively export your extension configuration by following the instructions in [Configure the function kit instance identically to the
> extension](https://firebase.google.com/docs/extensions/migration-best-practices#saving-config-for-future-migration).

## Determine your migration path

Firebase encourages all Firebase Extensions publishers to create
replacements for their extensions as function kits published on npm. You can
check if a function kit replacement is available for your extensions in a few
different ways:

- Go to the [Extensions page of the Firebase console](https://console.firebase.google.com/project/_/extensions) for your project. Each extension you have installed indicates if it has a function kit replacement available.
- Run `firebase ext:list` inside your Firebase project in a terminal
  to show which of your installed extensions have official replacements:

  ```bash
  firebase ext:list --project my-project
  ```

      i  extensions: ensuring required API firebaseextensions.googleapis.com is enabled...
      ✔  extensions: required API firebaseextensions.googleapis.com is enabled
      i  extensions: list of extensions installed in my-project:
      ┌────────────────────────────────────┬───────────┬────────────────────────────────┬────────┬─────────┬─────────────────────┬───────────────────────────────────────────────────┐
      │ Extension                          │ Publisher │ Instance ID                    │ State  │ Version │ Your last update    │ Replacement Kit                                   │
      ├────────────────────────────────────┼───────────┼────────────────────────────────┼────────┼─────────┼─────────────────────┼───────────────────────────────────────────────────┤
      │ firebase/firestore-bigquery-export │ firebase  │ firestore-bigquery-export-zbrp │ ACTIVE │ 0.3.2   │ 2026-06-10 18:35:03 │ @firebase-function-kits/firestore-bigquery-export │
      ├────────────────────────────────────┼───────────┼────────────────────────────────┼────────┼─────────┼─────────────────────┼───────────────────────────────────────────────────┤
      │ firebase/storage-resize-images     │ firebase  │ storage-resize-images          │ ACTIVE │ 0.3.6   │ 2026-06-03 17:41:24 │                                                   │
      └────────────────────────────────────┴───────────┴────────────────────────────────┴────────┴─────────┴─────────────────────┴───────────────────────────────────────────────────┘
      ⚠ Notice: Firebase Extensions will shut down on March 31, 2027. Learn more: https://firebase.google.com/docs/extensions/faq-and-troubleshooting

If an official function kit replacement is available for your extension, you can
migrate it using the [Migrate to function kits on npm](https://firebase.google.com/docs/extensions/users/migrate.md.txt#migrate-to-function-kits)
section.

If you can't find a published replacement, you can fork the extension code and
create your own replacement because all extensions are open source. To do this,
follow the [Migrate to a self-created function kit](https://firebase.google.com/docs/extensions/users/migrate-self-created.md.txt)
guide.

> [!NOTE]
> **Note:** Other developers can create unofficial function kit replacements. Google doesn't validate or advertise unofficial replacements, but if you find one and validate it yourself, you can use these migration guides to migrate to it.

|---|---|
| **Select migration path:** | [Migrate to function kits on npm](https://firebase.google.com/docs/extensions/users/migrate.md.txt) [Migrate to a self-created function kit](https://firebase.google.com/docs/extensions/users/migrate-self-created.md.txt) |

## Migrate to function kits on npm

### Check for known migration limitations

Before you start migrating an extension instance, check whether your setup uses
any of the following features that require a workaround or aren't yet supported
in function kits:

- **Custom Docker repositories and KMS keys require a manual workaround** Cloud Functions for Firebase doesn't support replacement system parameters for configuring a custom Docker repository or Customer-Managed Encryption Key (KMS key). If your extension configures either of these parameters, refer to the [FAQ workaround](https://firebase.google.com/docs/extensions/faq-and-troubleshooting.md.txt#docker-or-kms-workaround).

### Before you begin

You need to [set up the Firebase CLI](https://firebase.google.com/docs/cli.md.txt#setup_update_cli) and
[initialize a Firebase
project](https://firebase.google.com/docs/cli#initialize_a_firebase_project). When using the CLI, make sure
you're using `firebase-tools` version `>= 15.32.0`, which has the new migration
and function kit commands.

> [!NOTE]
> **Note:** All CLI commands throughout this guide include the `--project
> <project-id>` flag to explicitly specify your target project. If you are working in your default project configured in `.firebaserc`, you can omit the `--project` flag.

#### Required account permissions and roles

Depending on what needs to be created and configured by the Firebase CLI
during migration, the account you're using to authenticate with Firebase
and Google Cloud must have the following roles:

- `roles/firebaseextensions.editor`
- `roles/cloudbuild.builds.editor`
- `roles/artifactregistry.writer`
- `roles/run.developer`
- `roles/iam.serviceAccountUser`
- `roles/iam.serviceAccountCreator`
- `roles/cloudfunctions.admin` (if you need to do `setIamPermissions` for public endpoints)
- `roles/secretmanager.admin` (if using secrets)
- `roles/serviceusage.serviceUsageAdmin` (if you need to enable new APIs)

We recommend using an account that has installed extensions and deployed
functions before, since most of these permissions will already have been
granted. If your migrating account needs more roles, follow the
[Google Cloud IAM instructions](https://cloud.google.com/iam/docs/grant-role-console)
to add them.

#### Choose a CLI workflow

To migrate from an extension instance to a function kit available on npm, choose
one of the following options:

- **(Recommended)** Migrate using the `ext:migrate` CLI command. This command deploys your function kit replacement before uninstalling the extension it replaces.
- Migrate using the [function kits CLI commands](https://firebase.google.com/docs/extensions/users/migrate.md.txt#function-kits-cli). You can use separate commands to update your extension, install a function kit, configure it like the extension, deploy the kit, and uninstall the extension. This provides more flexibility for reordering commands or performing additional work between steps.

### Migrate using `ext:migrate`

Once per extension instance, start a migration by running:

```bash
firebase ext:migrate --project <project-id>
```

This command walks you through:

1. Selecting an extension to migrate that has an official function kit replacement available.
2. Selecting a specific instance of that extension.
3. Updating the extension to its latest version if necessary.
4. Installing the function kit, configuring an instance identically to how the extension instance is configured.
5. Deploying the function kit.
6. Verifying that the function kit deployed successfully and that all lifecycle hooks, if any, ran.
7. Uninstalling the extension instance.

If you know the specific extension or extension instance you want to migrate,
specify it using the following command-line flags:

```bash
firebase ext:migrate --extension firebase/firestore-bigquery-export --project <project-id>

# or

firebase ext:migrate --ext-instance firestore-bigquery-export-abcd --project <project-id>
```

If you know the specific package you want to migrate to, especially if it's not
an official replacement package listed by Google, specify it using the
`--package` flag:

```bash
firebase ext:migrate --ext-instance firestore-bigquery-export-abcd --package @firebase-function-kits/firestore-bigquery-export --project <project-id>
```

> [!WARNING]
> **Warning:** If you call `ext:migrate` with `--force`, it immediately deletes the extension after deploying the replacement without any verification. This can result in brief downtime even in a successful migration, as it can take a few minutes for Eventarc to fully provision and for the kit replacement to process events for any event-triggered extension.

#### Verify a function kit deployment

To verify that the `firebase deploy` of the kit had no errors, check the
deployment logs to see if any lifecycle hooks were triggered. Popular
extensions, such as Stream Cloud Firestore to BigQuery, use lifecycle
hooks. The following is an example of how a lifecycle hook looks when triggered:

    i  functions: Executing afterFirstDeploy lifecycle hook targeting: kit-firestore-bigquery-export-initBigQuerySync...
    ✔  functions: Successfully queued task for lifecycle hook kit-firestore-bigquery-export-initBigQuerySync in queue projects/my-project/locations/europe-west1/queues/kit-firestore-bigquery-export-initBigQuerySync.
    i  functions: View logs for afterFirstDeploy at: https://console.cloud.google.com/logs/query;query=resource.type%3D%22cloud_run_revision%22%0Aresource.labels.service_name%3D%22kit-firestore-bigquery-export--initbigquerysync%22%0Aresource.labels.location%3D%22europe-west1%22;project=my-project

These log messages confirm the following:

- A lifecycle hook was found and executed.
- A task was queued in the lifecycle hook's associated task queue.
- A link to Cloud Logging was provided so you can validate that the task completed without errors.

Follow the logs link to the Google Cloud console to validate that there are no
errors in the logs and your task queue event was successfully processed. If the
lifecycle event didn't execute successfully, you can retrigger it by running:

```bash
firebase functions:lifecycle:run <hook-name> <codebase>
```

If you're deploying a function kit instance for the first time, run:

```bash
firebase functions:lifecycle:run afterFirstDeploy <kit-instance-id>
```

If at any time during validation you decide you want to stop or undo this
migration, you can uninstall the kit using the instructions in
[Uninstall the extension](https://firebase.google.com/docs/extensions/migration-best-practices.md.txt#undoing-migration).

Once you've verified that the initial deployment of your function kit has
completed successfully, you need to validate that the functionality of the kit
is actually working as expected. Because the extension itself is still running,
you need to be careful that what you're checking is not just that one of the two
has worked, since the extension has been and will continue to work.

In the case where the processing isn't changed and you don't see duplicate
results from the extension and kit, the best option is to directly examine the
logs for the kit after triggering the kit's functionality.

**Worked Example:** Stream Cloud Firestore to BigQuery

With the Stream Cloud Firestore to BigQuery Extension writes to both
the Raw Changelog Table (`*_raw_changelog`) and latest view table
(`*_raw_latest`) will deduplicate if the same event is delivered to the kit and
the extension. So you can't use the presence of any rows or duplicate rows in
BigQuery to validate the kit is working.

You can view functions logs shortly after writing to your Firestore collection
using `firebase functions:logs` and look for a log entry that indicates it
successfully processed a write. For this kit with the default instance ID
of `firestore-bigquery-export` would look like:

```bash
2026-09-25T19:52:46.328612Z I kit-firestore-bigquery-export-fsexportbigquery: Started execution of extension
2026-09-25T19:52:46.328644Z I kit-firestore-bigquery-export-fsexportbigquery: {"message":"Firestore event received by onDocumentWritten trigger","document_name":"projects/extensions-eventarc-testing/databases/(default)/documents/exported-messages/cmGP6XLyksqGdw2OgTOq","operation":0,"event_id":"9f59a2a4-1a5e-4c41-a32d-561e3c734502"}
2026-09-25T19:52:46.616064Z I kit-firestore-bigquery-export-fsexportbigquery: Completed execution of extension
2026-09-2
```

> [!NOTE]
> **Note:** The specific Firestore event received log `document_name` will vary based on your configuration.

If you have a lot of logs, you can filter down to a specific kit function
using the following command:

```bash
firebase functions:log --only <function name>
```

To find the specific function names for a kit instance, you can use the
following command:

```bash
firebase functions:list | grep kit-<kit instance id>
```

For this example:

```bash
firebase functions:list | grep kit-firestore-bigquery-export
│ kit-firestore-bigquery-export-fsexportbigquery  │ v2      │ google.cloud.firestore.document.v1.written                    │
│ kit-firestore-bigquery-export-initBigQuerySync  │ v2      │ taskQueue                                                     │
│ kit-firestore-bigquery-export-setupBigQuerySync │ v2      │ taskQueue                                                     │
│ kit-firestore-bigquery-export-syncBigQuery      │ v2      │ taskQueue                                                     │
```

#### Review the function kit README

Some kits might require additional work beyond what is handled automatically by
function kits. Review the `README` for the kit you're installing and follow any
additional instructions.

### Migrate using the function kits CLI

Before you begin, identify and write down the instance ID of the extension you'd
like to migrate to a kit and the npm package name of its replacement kit. You
can find both of these using the output of `firebase ext:list`. See
[Determining your migration path](https://firebase.google.com/docs/extensions/users/migrate.md.txt#migration-path) for an example of using
`ext:list`.

#### 1. Upgrade your extension instance to the latest version

You **must** update your extension to the latest version to minimize the
difference between your extension instance and its replacement kit. If your
extension isn't upgraded, there may be significant, breaking changes between
your extension instance and its kit replacement. The exported configuration may
not match what the kit expects because of parameter changes across versions.

Use one of the following options to update your extension, depending on where it
was installed:

- From the [Firebase console](https://console.firebase.google.com/project/_/extensions)
- From the Firebase CLI using:
  - `firebase ext:update <extension-instance-id> --project <project-id> firebase deploy --only extensions --project <project-id>`

If you skip this step, the CLI prompts you to upgrade when exporting
configuration if your extension isn't on the latest version.

#### 2. Review and install the replacement function kit instance

You can install the function kit using the following CLI command:

```bash
firebase functions:kits:install --template migration --no-configure --package <npm-package-name> --project <project-id>
```

When you pick an instance ID for your kit during installation, make sure to
write it down for use later in the migration instructions.

Once the kit is installed, a new directory is created inside your
Firebase project with a location like `function-kits/<kit-name>/source`
that contains the npm package with the kit replacing your extension and a basic
`index.ts` file that exports those functions for Firebase to deploy and
set custom configuration.

Review the [README](https://firebase.google.com/docs/extensions/users/migrate.md.txt#review-function-kit-readme) for the kit and follow any
additional instructions listed there.

If you have multiple instances of the kit in the same project, you can repeat
this command to create new instances of the same kit. You can also deploy a
single kit instance to two different Firebase projects with different
configurations (for example, a staging project and a production project). To
learn more about these advanced setups, see
[Advanced migrations](https://firebase.google.com/docs/extensions/users/migrate.md.txt#advanced-migrations).

**Worked example:**

```bash
firebase functions:kits:install --template migration --no-configure --package @firebase-function-kits/firestore-bigquery-export --project my-project
```

#### 3. Configure the function kit instance identically to the extension

You need to customize this kit instance with a configuration identical to the
extension it's replacing. You can export your extension instance configuration
into a `.env` file, which stores parameter, environment variable, and secret
reference configuration data for all Cloud Functions, including kits. To
export it directly into the configuration file of your kit, run:

```bash
firebase ext:export --mode functions --instance <extension-instance-id> --kit-instance <kit-instance-id> --project <project-id>
```

At the end of this step, the configuration information for this instance is
stored in a project-specific `.env` file in your instance config directory, such
as:
`function-kits/<kit-name>/config-<instance-id>/.env.<project-id>`

> [!NOTE]
> **Note:** If you haven't upgraded your extension to the latest version before exporting, the export command prompts you to do so.

#### 4. Deploy and verify the kit replacement

Now that the kit is installed and available as a set of functions, you can
deploy the kit replacement. Function kits work like standard functions, where
each kit instance acts as a separate
[codebase](https://firebase.google.com/docs/functions/organize-functions.md.txt#organize_functions_in_codebases)
for organizing your functions. You can choose to deploy all of your functions or
just a specific kit instance. While migrating a single extension instance,
deploy only that kit instance.

If your kit uses any new parameters that weren't present in the extension
instance you migrated from, the Firebase CLI prompts you for them at the
beginning of the deployment process. This isn't expected in this worked example
from an up-to-date `firestore-bigquery-export` extension, but many kits prompt
for a new parameter for any event trigger source used by the kit. As part of
this migration, updated kits use 2nd gen functions where extensions previously
used 1st gen functions. In 2nd gen, functions are located near their event
sources and added as an additional parameter. In future updates, if new
parameters are added, the CLI prompts you on the next deployment.

**Worked example:**

```bash
firebase deploy --only functions:firestore-bigquery-export --project my-project
```

**Output:**

    === Deploying to 'my-project'...
    i  deploying functions
    i  functions: Loaded environment variables from function-kits/firestore-bigquery-export/config-firestore-bigquery-export/.env.my-project
    i  functions: ensuring required API bigquery.googleapis.com is enabled...
    i  functions: ensuring required API cloudtasks.googleapis.com is enabled...
    ✔  functions: required APIs are enabled
    i  functions: granting declarative IAM roles to managed service account:
       - BigQuery Data Editor
       - BigQuery User
       - Cloud Datastore User
       - Eventarc Event Receiver
       - roles/run.invoker
    ✔  functions: successfully granted IAM roles
    i  functions: creating Node.js 22 (2nd Gen) function kit-firestore-bigquery-export-fsexportbigquery(us-central1)...
    i  functions: creating Node.js 22 (2nd Gen) function kit-firestore-bigquery-export-initBigQuerySync(us-central1)...
    i  functions: creating Node.js 22 (2nd Gen) function kit-firestore-bigquery-export-setupBigQuerySync(us-central1)...
    ✔  functions[kit-firestore-bigquery-export-fsexportbigquery(us-central1)] Successful create operation.
    ✔  functions[kit-firestore-bigquery-export-initBigQuerySync(us-central1)] Successful create operation.
    ✔  functions[kit-firestore-bigquery-export-setupBigQuerySync(us-central1)] Successful create operation.
    i  functions: Executing afterFirstDeploy lifecycle hook targeting: kit-firestore-bigquery-export-initBigQuerySync...
    ✔  functions: Successfully queued task for lifecycle hook kit-firestore-bigquery-export-initBigQuerySync in queue projects/my-project/locations/us-central1/queues/kit-firestore-bigquery-export-initBigQuerySync.
    ✔  Deploy complete!

> [!NOTE]
> **Note:** It can take a few minutes for Eventarc to fully provision and start accepting events. We recommend waiting a few minutes before verifying your kit if it's event triggered. If you delete your extension immediately without verification, you might have a brief period of downtime while provisioning finishes.

To verify that the `firebase deploy` of the kit had no errors, check the
deployment logs to see if any lifecycle hooks were triggered. Popular
extensions, such as Stream Cloud Firestore to BigQuery, use lifecycle
hooks. The following is an example of how a lifecycle hook looks when triggered:

    i  functions: Executing afterFirstDeploy lifecycle hook targeting: kit-firestore-bigquery-export-initBigQuerySync...
    ✔  functions: Successfully queued task for lifecycle hook kit-firestore-bigquery-export-initBigQuerySync in queue projects/my-project/locations/europe-west1/queues/kit-firestore-bigquery-export-initBigQuerySync.
    i  functions: View logs for afterFirstDeploy at: https://console.cloud.google.com/logs/query;query=resource.type%3D%22cloud_run_revision%22%0Aresource.labels.service_name%3D%22kit-firestore-bigquery-export--initbigquerysync%22%0Aresource.labels.location%3D%22europe-west1%22;project=my-project

These log messages confirm the following:

- A lifecycle hook was found and executed.
- A task was queued in the lifecycle hook's associated task queue.
- A link to Cloud Logging was provided so you can validate that the task completed without errors.

Follow the logs link to the Google Cloud console to validate that there are no
errors in the logs and your task queue event was successfully processed. If the
lifecycle event didn't execute successfully, you can retrigger it by running:

```bash
firebase functions:lifecycle:run <hook-name> <codebase>
```

If you're deploying a function kit instance for the first time, run:

```bash
firebase functions:lifecycle:run afterFirstDeploy <kit-instance-id>
```

If at any time during validation you decide you want to stop or undo this
migration, you can uninstall the kit using the instructions in
[Uninstall the extension](https://firebase.google.com/docs/extensions/migration-best-practices.md.txt#undoing-migration).

Once you've verified that the initial deployment of your function kit has
completed successfully, you need to validate that the functionality of the kit
is actually working as expected. Because the extension itself is still running,
you need to be careful that what you're checking is not just that one of the two
has worked, since the extension has been and will continue to work.

In the case where the processing isn't changed and you don't see duplicate
results from the extension and kit, the best option is to directly examine the
logs for the kit after triggering the kit's functionality.

**Worked Example:** Stream Cloud Firestore to BigQuery

With the Stream Cloud Firestore to BigQuery Extension writes to both
the Raw Changelog Table (`*_raw_changelog`) and latest view table
(`*_raw_latest`) will deduplicate if the same event is delivered to the kit and
the extension. So you can't use the presence of any rows or duplicate rows in
BigQuery to validate the kit is working.

You can view functions logs shortly after writing to your Firestore collection
using `firebase functions:logs` and look for a log entry that indicates it
successfully processed a write. For this kit with the default instance ID
of `firestore-bigquery-export` would look like:

```bash
2026-09-25T19:52:46.328612Z I kit-firestore-bigquery-export-fsexportbigquery: Started execution of extension
2026-09-25T19:52:46.328644Z I kit-firestore-bigquery-export-fsexportbigquery: {"message":"Firestore event received by onDocumentWritten trigger","document_name":"projects/extensions-eventarc-testing/databases/(default)/documents/exported-messages/cmGP6XLyksqGdw2OgTOq","operation":0,"event_id":"9f59a2a4-1a5e-4c41-a32d-561e3c734502"}
2026-09-25T19:52:46.616064Z I kit-firestore-bigquery-export-fsexportbigquery: Completed execution of extension
2026-09-2
```

> [!NOTE]
> **Note:** The specific Firestore event received log `document_name` will vary based on your configuration.

If you have a lot of logs, you can filter down to a specific kit function
using the following command:

```bash
firebase functions:log --only <function name>
```

To find the specific function names for a kit instance, you can use the
following command:

```bash
firebase functions:list | grep kit-<kit instance id>
```

For this example:

```bash
firebase functions:list | grep kit-firestore-bigquery-export
│ kit-firestore-bigquery-export-fsexportbigquery  │ v2      │ google.cloud.firestore.document.v1.written                    │
│ kit-firestore-bigquery-export-initBigQuerySync  │ v2      │ taskQueue                                                     │
│ kit-firestore-bigquery-export-setupBigQuerySync │ v2      │ taskQueue                                                     │
│ kit-firestore-bigquery-export-syncBigQuery      │ v2      │ taskQueue                                                     │
```

#### 5. Uninstall the extension

When you've verified your deployed function kit, you can uninstall your
extension so that you're not duplicating its behavior once for the kit and once
for the extension. You can uninstall all extensions from the Firebase CLI
regardless of how you installed them if you pass the `--immediate` flag:

```bash
firebase ext:uninstall <extension-instance-id> --project <project-id> --immediate
```

**Worked example:**

```bash
firebase ext:uninstall firestore-bigquery-export --project my-project --immediate
```

**Output:**

    i  extensions: uninstalling firestore-bigquery-export...
    i  extensions: deleting extension instance resources in project my-project...
    ✔  extensions: successfully uninstalled firestore-bigquery-export

## Advanced migrations

You can have extensions in multiple Firebase projects that you want to
manage with a single codebase. For example, if you deploy the same
infrastructure to a `testing` environment and a `production` environment, each
of which has a `documents` Cloud Firestore instance that you export to
BigQuery, you might have two instances of the
`firestore-bigquery-export` extension installed:

- `export-documents-testing`
- `export-documents-production`

If you migrated these two extension instances to two function kit instances in a
single codebase when working with the Firebase CLI and deployed using
`firebase deploy --project testing` and `firebase deploy --project production`,
each deploy would create two instances in both the `testing` and `production`
environments.

Instead, replace the two extension instances with one function kit instance of
`firestore-bigquery-export` deployed to multiple projects, where each project
has its own configuration. Your configuration directory for the instance should
look like the following:

- `config-export-documents/`
  - `.env.testing`
  - `.env.production`

Each deployment to `testing` and `production` creates one instance of your kit
with the corresponding configuration. The existing CLI commands create this
setup as long as you pass the `--project` flag in each invocation of
`ext:migrate` or `functions:kits:install`.

**Worked example:**

```bash
firebase functions:kits:install --package @firebase-function-kits/firestore-bigquery-export --project testing --no-configure --template migration
```

    ✔ What would you like to name this kit? firestore-bigquery-export
    ✔ What would you like to name this instance? export-documents
    ✔  Wrote function-kits/firestore-bigquery-export/source/package.json
    ✔  Wrote function-kits/firestore-bigquery-export/source/tsconfig.json
    ✔  Wrote function-kits/firestore-bigquery-export/source/.gitignore
    ✔  Wrote function-kits/firestore-bigquery-export/source/src/index.ts
    i  functions: Running npm install
    ✔  Wrote configuration info to firebase.json
    ✔  functions: Function kit firestore-bigquery-export successfully installed.

```bash
# This creates the export-documents instance with an empty .env.testing file
# for the testing project. Now populate it via export:
firebase ext:export --mode functions --instance export-documents-testing \
  --kit-instance export-documents --project testing

# Repeat the export for production into the same kit instance to create
# .env.production from the export-documents-prod instance:
firebase ext:export --mode functions --instance export-documents-prod \
  --kit-instance export-documents --project production
```

> [!NOTE]
> **Note:** Some console output has been omitted for brevity.

You now have a single kit instance configured to deploy to your `testing` and
`production` projects with their respective configurations. If you create an
instance in the `testing` project and run the `functions:kits:install` command
for the same package in the `production` project, you're prompted with the
option to reuse the instance configured for `testing` or install a second
instance.