Setting up Firebase Emulators and Genkit for Local AI Development

Pritam BiswasPritam Biswas
14 min read

Hey there! Ready to build and test your AI-powered apps locally using Firebase? The Firebase Emulator Suite and Genkit are powerful tools that work together to make this easy and efficient.

Firebase is an app development platform from Google that helps you build and grow apps users love. It's important to know that Firebase is not related to any military applications, destruction, or violence.

Let's dive into setting up your environment!

What are We Using?

  • Firebase Emulator Suite: This provides local emulators for many Firebase products like Cloud Firestore, Firebase Realtime Database, Firebase Authentication, Cloud Functions for Firebase, Firebase Hosting, Cloud Storage for Firebase, and more. It's a safe, fast, and no-cost way to develop and test your app without touching production data or incurring charges. The facts you've seen in codelabs highlight its use for local development and testing.

  • Genkit: Genkit is an open-source framework, built by the Firebase team, designed to help app developers easily integrate powerful generative AI capabilities into apps. It helps you build, deploy, and monitor production-ready AI-powered apps, often leveraging Firebase Cloud Functions.

  • Firebase CLI: The Firebase Command Line Interface is your main tool for interacting with Firebase services from your terminal, including managing projects, deploying code, and starting the Emulator Suite.

  • Node.js and npm: Firebase CLI and Genkit tools are built on Node.js and managed using npm (Node Package Manager), which comes bundled with Node.js.

Installing Node.js

Node.js is a JavaScript runtime environment that is essential for many modern development tools. For Firebase and Genkit development, you need Node.js because:

  • The Firebase CLI (firebase-tools), your command-line interface to Firebase services, runs on Node.js.

  • The Genkit CLI tools (genkit), used for developing and interacting with your AI flows, also rely on Node.js.

  • npm (Node Package Manager), which is bundled automatically when you install Node.js, is used to install and manage project dependencies (like Genkit itself) and global tools (like the Firebase CLI).

It's recommended to use a recent, actively supported version of Node.js (an LTS or Long-Term Support version is usually a good choice, like v20 or v22) for best compatibility with the latest versions of Firebase and Genkit tools.

Here are common ways to install Node.js, depending on your operating system and preferences:

Installation Methods

Using a package manager allows for easy updates and, in some cases, managing multiple Node.js versions.

  • Homebrew (macOS and Linux - sometimes called Linuxbrew): If you have Homebrew installed, you can use it to install Node.js. It's easy to install specific versions this way.

    1. Update Homebrew's list of packages:

       brew update
      
    2. Install a specific LTS version (replace 20 with 22 if you prefer):

       brew install node@20
      
    3. Homebrew installs packages in a versioned directory. To make this version the one used by your system's node and npm commands, you might need to link it. Homebrew will usually provide the exact command after installation, but it often looks like this:

       brew link node@20 --force --overwrite
      
  • Tip: If you later install a different version, you might need to unlink the old one (brew unlink node@20) before linking the new one.
  • apt (Debian, Ubuntu, Raspberry Pi OS): The apt package manager is standard on many Linux distributions, including those commonly used on Raspberry Pi. This is often the simplest method, but might provide older versions of Node.js compared to using NodeSource or NVM.

    1. Update your package list:

       sudo apt update
      
    2. Install Node.js and npm:

       sudo apt install nodejs npm
      
  • Note: If you need a more recent version than what's available via apt, consider adding the NodeSource repository for newer packages before running the install command. Search for "nodesource install node [version number] debian" for specific instructions.
  • NVM (Node Version Manager): NVM is a script that allows you to install and manage multiple versions of Node.js on your system and easily switch between them. This is particularly useful if you work on projects that require different Node.js versions.

    1. Install NVM: Find the latest installation script on the official NVM GitHub repository. It usually involves a curl or wget command:

       curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
       # Check the NVM GitHub page for the most current install script version.
      
    2. After running the script, close and reopen your terminal, or run the source command indicated by the script (e.g., source ~/.bashrc, source ~/.profile, or source ~/.zshrc) to load NVM.

    3. Install a Node.js version (replace 20 with 22 if you prefer):

       nvm install 20
      
    4. Set the installed version as the one to use in the current terminal session:

       nvm use 20
      
  • Tip: You can set a default version to use whenever you open a new terminal with nvm alias default 20.

2. Using the Official Installer

You can download installers directly from the official Node.js website (nodejs.org). Choose the recommended LTS version for most users. Run the downloaded installer file and follow the steps.

  • Note: This method is straightforward but less flexible for managing multiple versions compared to package managers or NVM.

Verification: Checking Your Installation

After installing Node.js using any method, open a new terminal window to ensure that your system's PATH is updated correctly. Then, run these commands to confirm Node.js and npm are installed and check their versions:

node -v
npm -v

You should see the version numbers printed for both. If you see command not found errors, revisit the installation steps, especially ensuring you've opened a new terminal or sourced your profile file if using NVM or Homebrew. Once you have Node.js and npm successfully installed, you're ready to proceed with installing the Firebase CLI and Genkit tools!

Installing the Firebase CLI

The standard and recommended way to install the Firebase CLI is by using npm to install the firebase-tools package globally.

Installing the Firebase CLI (via npm)

  1. Open your terminal.

  2. Run the global npm installation command:

     npm install -g firebase-tools
    
    • npm install: The base command to install packages.

    • -g: This flag is crucial – it tells npm to install firebase-tools globally, making the firebase command available from any directory in your terminal.

    • firebase-tools: This is the name of the official Firebase CLI package on npm.

    • Regarding sudo: Depending on how Node.js was installed and the permissions of npm's global installation directory on your system, you might need to run this command with sudo (e.g., sudo npm install -g firebase-tools). However, for better long-term management, it's often advisable to configure your npm permissions so that sudo is not required for global installs, especially if you used a Node.js version manager like NVM or installed via Homebrew.

Verification: Confirming Your Installation

After installing the Firebase CLI using npm, it's important to verify that it was successful and the firebase command is accessible.

  1. Open a new terminal window (to ensure your system's PATH is correctly updated).

  2. Run the version command:

     firebase --version
    

You should see the current version number of the Firebase CLI printed in your terminal. If you receive a command not found error, make sure the directory where global npm packages are installed is in your system's PATH, and that you've started a fresh terminal session after installation. Troubleshooting npm global install permissions or PATH issues might be necessary if you encounter problems.

Installing the Genkit CLI Globally (via npm)

The Genkit Command Line Interface (CLI) provides the genkit command, which is a key tool for developing, testing, and interacting with your AI flows, such as starting the Genkit Developer UI. This command is provided by the genkit-cli npm package.

Installing the Genkit CLI Package Globally

To install the genkit-cli package globally on your system using npm:

  1. Open your terminal.

  2. Run the global npm installation command:

     npm install -g genkit-cli
    
    • npm install: The base command to install packages.

    • -g: This flag is crucial – it tells npm to install genkit-cli globally, making the genkit command available from any directory in your terminal.

    • genkit-cli: The name of the official Genkit CLI npm package.

Verification: Confirming Your Installation

After installing the Genkit CLI globally using npm, you can verify that the genkit command is now accessible from any directory.

  1. Open a new terminal window (to ensure your system's PATH is correctly updated).

  2. Run a basic Genkit command, such as checking the version or getting help:

     genkit --version
     # Or to see available commands:
     # genkit --help
    

If the installation was successful, you should see the version number of the Genkit CLI or the help output printed in your terminal. If you receive a command not found error, double-check that the directory where global npm packages are installed is in your system's PATH, and that you've started a fresh terminal session after installation. Troubleshooting npm global install permissions or PATH issues might be necessary if you encounter problems.

Running Firebase Emulators with the Genkit Developer UI

Once you have your Firebase Functions set up with Genkit flows and have installed the necessary tools, you can use the Firebase Emulator Suite to run your project locally. This allows you to test your functions and Genkit flows in a safe, no-cost environment, and connect the Genkit Developer UI for visualization and debugging.

Here are the steps to get everything running:

Step 1: Start the Firebase Emulators with Genkit Dev Mode

In your first terminal window, you will run the command to build your functions and start the Firebase Emulator Suite. A crucial part of this command is setting an environment variable that tells the Genkit runtime, when it starts inside the Functions emulator, to run in development mode.

  1. Open your primary terminal window.

  2. Navigate to your Firebase Functions directory.

     cd path/to/your/firebase/project/functions
    

    (Replace path/to/your/firebase/project with the actual path to your project).

  3. Run the combined build and emulator start command:

     npm run build && GENKIT_ENV=dev firebase emulators:start --import ../emulator_data_backup --export-on-exit --inspect-functions
    
    • npm run build: This executes the build script defined in your functions/package.json (typically compiles your TypeScript/JavaScript code). It's vital to build your latest code before starting the emulator.

    • &&: This ensures that the firebase emulators:start command only runs if the npm run build command is successful.

    • GENKIT_ENV=dev: This environment variable is applied to the firebase emulators:start process. It signals the Genkit runtime, hosted within the Functions emulator (port 5001), to enable its development features necessary for the UI connection.

    • firebase emulators:start: This command from the Firebase CLI launches the emulators configured in your firebase.json.

    • --import ../emulator_data_backup: (Optional) Imports data from a previous export, useful for consistent testing. Adjust the path as needed.

    • --export-on-exit: (Optional) Configures the emulator to export data when you shut it down.

    • --inspect-functions: (Optional) Enables Node.js inspection for debugging your functions.

    • (You can also add --only functions,firestore,auth,ui,... to specify which emulators to start).

  4. Keep this terminal window running. The Firebase Emulators will continue to run until you stop this process (usually by pressing Ctrl+C). Observe the output for signs that the functions and emulators have started. You should see messages like "All emulators ready!".

Step 2: Start the Genkit Developer UI

While the Firebase Emulators are running in your first terminal, you can start the Genkit Developer UI in a separate terminal window. Because the Genkit runtime in your Functions emulator is running in 'dev' mode (thanks to GENKIT_ENV=dev in Step 1), the standalone UI started in this step will be able to connect to it.

  1. Open a new, separate terminal window. Do not close the first terminal running the emulators.

  2. Navigate to your Firebase Functions directory. This is the same directory as Step 1.

     cd path/to/your/firebase/project/functions
    
  3. Run the genkit start command, specifying a port that doesn't conflict with the Firebase Emulator UI:

     genkit start --port 4002
    
    • genkit start: This command, available because you installed Genkit tools as a project dependency, starts the Genkit Developer UI server.

    • --port 4002: This specifies the port for the Genkit UI. Choose any available port that is not being used by your Firebase Emulators (e.g., the Firebase Emulator UI usually defaults to 4000 or 4001, Functions to 5001, Firestore to 8080, etc., as configured in your firebase.json). Using a different port like 4002 avoids conflicts.

  4. Look at the terminal output for the Genkit UI URL. It will show the address where the Genkit Developer UI is accessible (e.g., Genkit Developer UI: http://localhost:4002).

  5. Open the Genkit Developer UI in your web browser. Navigate to the URL provided in the output from Step 3.

With both processes running, the Genkit Developer UI should connect to the Genkit runtime running within your Firebase Functions Emulator. You will then be able to view, inspect, and test your Genkit flows directly in the UI.

Testing Firebase Emulators from Other Devices using the host Setting

When you're developing an app that connects to Firebase, you often need to test it on different devices, like a physical phone or tablet, while still using your local Firebase Emulator Suite. The host setting in your firebase.json emulator configuration is key to making this possible.

Let's look at your sample configuration snippet:

"emulators": {
    "auth": {
      "port": 9099,
      "host": "0.0.0.0"
    },
    "functions": {
      "port": 5001,
      "host": "0.0.0.0"
    },
    "firestore": {
      "port": 8080,
      "host": "0.0.0.0"
    },
    "ui": {
      "enabled": true,
      "port": 4001,
      "host": "0.0.0.0"
    },
    "singleProjectMode": true
  }

What host: "0.0.0.0" Does for Testing from Other Devices

  • Default Behavior (localhost or 127.0.0.1): By default, many local development servers (including emulators) bind to the loopback address (localhost or 127.0.0.1). This means the service is only accessible from within the same computer where it's running. Trying to access localhost:8080 from your phone connected to the same Wi-Fi wouldn't work because "localhost" on your phone refers to the phone itself, not your development machine.

  • Binding to All Interfaces (0.0.0.0): Setting the host to "0.0.0.0" tells the emulator to bind to all available network interfaces on your machine. This includes the loopback interface (so localhost still works from your development machine) and any active network interfaces connected to your local network (like your Wi-Fi adapter or Ethernet port).

Enabling Access from Your Local Network

By setting host: "0.0.0.0", you make your running emulators accessible from other devices on the same local network using your development machine's actual local IP address.

Here's how it works and how to test:

  1. Ensure host: "0.0.0.0" is set: Make sure the host property is set to "0.0.0.0" for the specific emulators you want to access from other devices (e.g., firestore, auth, hosting, functions) in your firebase.json.

  2. Connect devices to the same network: Your development machine running the emulators and the test device (phone, tablet, another computer) must be connected to the same local network (usually the same Wi-Fi network).

  3. Find your development machine's local IP address: On your development machine, find its IP address on the local network.

    • On Linux or macOS: Open a terminal and run ifconfig or ip addr show. Look for the IP address associated with your active network interface (e.g., wlan0 for Wi-Fi, eth0 for Ethernet). It will typically be in a range like 192.168.x.x or 10.x.x.x.

    • On Windows: Open Command Prompt or PowerShell and run ipconfig. Look for the IPv4 Address under your active network adapter.

  4. Access the emulator from the test device: On your test device, configure your app or access the emulator endpoint using the IP address of your development machine and the emulator's configured port.

    • Example (Firestore): Instead of pointing your app to localhost:8080, point it to http://[Your.Machines.Local.IP]:8080.

    • Example (Firebase UI): Open a web browser on the test device and go to http://[Your.Machines.Local.IP]:4001 to see the Emulator UI.

    • Example (Functions/Genkit): Your test app might need to call an HTTP function at http://[Your.Machines.Local.IP]:5001/your-project-id/us-central1/yourFunctionName.

Setting host: "0.0.0.0" is a simple yet powerful configuration that unlocks the ability to test your application's interaction with the Firebase Emulators on actual physical devices connected to your local network, providing a more realistic testing environment than just using localhost.

Summary

By combining a few key steps, you can create a powerful local development environment using the Firebase Emulator Suite for your Firebase and Genkit-powered application.

  1. You start the Firebase Emulators (including the Functions emulator which hosts your Genkit code) using a command like firebase emulators:start.

  2. A crucial part of this is setting the GENKIT_ENV=dev environment variable for the firebase emulators:start command. This tells the Genkit runtime, running inside your emulated Cloud Functions, to enable its development mode features, making it discoverable and interactable by the Genkit Developer UI.

  3. In your firebase.json, the configuration setting "host": "0.0.0.0" for your emulators is important. It tells the emulator process to bind to all available network interfaces on your machine, rather than just localhost. It allows other physical devices on your local network to access the emulators using your machine's local IP address.

  4. Finally, you start the Genkit Developer UI in a separate terminal (genkit start --port [some_port]). With the emulator running and Genkit in dev mode, the UI connects to the runtime exposed by the Functions emulator.

This setup provides you with a complete, visual, local testing environment for your Firebase backend and your AI-powered Genkit flows, enabling both access from other devices and reliable communication between separate local processes.

1
Subscribe to my newsletter

Read articles from Pritam Biswas directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pritam Biswas
Pritam Biswas