Skip to content

Configuration

Firenook reads your project the way the official Firebase CLI does: from firebase.json, .firebaserc and the command line. This page lists every key it reads, what it skips, and the environment variables that change what it does. For the flags, see CLI commands.

Every command uses the first firebase.json in the current folder or a folder above it, up to the root of the disk, as the official CLI finds it. Run in functions/, where npm run serve runs, a command finds the project’s file. .firebaserc is the one beside it. --config names another file, relative to the current folder. With no file to find, every command that needs one stops:

Firenook: No firebase.json in ~/demo-shop or a folder above it; run firenook init in the project directory or pass --config

An emulator starts when firebase.json configures it, exactly as the official CLI decides:

Emulator Configured by
Firestore a top-level firestore section, or emulators.firestore
Storage a top-level storage section, or emulators.storage
Functions a top-level functions or extensions section, or emulators.functions or emulators.extensions
Auth emulators.auth
Pub/Sub emulators.pubsub

Eventarc and Cloud Tasks start with Functions. The hub always runs. The console and the logging listener run unless emulators.ui.enabled is false. When firebase.json configures Functions but names no codebase and no Extensions, Functions, Eventarc and Cloud Tasks are not started, and a notice says so. --only narrows the list further. With nothing configured, Firenook stops with No emulators to start, run firenook init to get started.

Key What Firenook does with it
firestore.rules The Firestore Security Rules file, reloaded when it changes
firestore.indexes The composite indexes file. Indexes are not enforced, as officially; the console reads the file to say whether a query’s index is declared. A file that cannot be read is a warning, not an error.
firestore as an array Several databases: each entry is {database, rules, indexes}, and one entry may leave out database for (default). Every listed database is served.
storage.rules The Storage Security Rules file, for every bucket
storage as an array {target, rules} entries, with each target’s buckets from .firebaserc or --storage-bucket. A target’s rules govern every bucket it maps to.
functions.source The codebase folder. Default: functions
functions.codebase The codebase’s name
functions.ignore Files that do not trigger a reload when they change
functions.configDir Where the codebase’s .env files are read from. Default: the source folder
functions.runtime The Node the codebase deploys on, such as nodejs22. It comes before engines.node in the codebase’s package.json. See Node per codebase.
functions as an array Several codebases, each with the keys above
extensions Extension instances: each key is an instance id, each value a registry reference or a local path. See Extensions.
emulators.<name>.port The port of firestore, auth, storage, functions, pubsub, eventarc, tasks, hub, ui or logging. See Ports.
emulators.<name>.host The address to listen on. Default: localhost. See Ports.
emulators.firestore.websocketPort The Firestore requests WebSocket’s port
emulators.ui.enabled false turns off the console and the logging listener. --ui turns them on all the same, as the official --ui does.
emulators.singleProjectMode Whether to warn about requests that name another project. Default: true

A storage section is optional: without one, Storage starts on emulators.storage with open default rules for the project’s bucket.

An invalid indexes file is reported when the emulators start, and the start goes on:

firenook: the Firestore indexes in ./firestore.indexes.json were not read (invalid index JSON: trailing comma at line 3 column 117); the console explains the queries of database "(default)" as if it declared none

As in the official emulator, every Firestore database and every Storage bucket is governed by some rules, or refuses clients:

  • A Firestore database the firestore list leaves out follows the rules of the (default) entry, or of the first entry when there is no (default), and follows them as they change. The console’s Rules page says which rules govern such a database.
  • A Storage target mapped to several buckets applies its rules to each of them.
  • A bucket no target maps to refuses every client request with Permission denied. Storage Emulator has no loaded ruleset.

The official emulators Firenook does not implement are skipped with a warning, and the rest of the project starts:

Firenook: firebase.json configures the hosting emulator, which Firenook does not implement; skipping it.

That applies to emulators.database, emulators.hosting, emulators.dataconnect and emulators.apphosting. Naming one of them in --only is an error. Top-level sections for products Firenook does not emulate, such as hosting, database or remoteconfig, are not read.

Any other key under emulators is an error:

Firenook: Unsupported configured emulator: frobnicate. Valid emulators keys are firestore, auth, storage, functions, pubsub, hub, ui, logging, eventarc, tasks, extensions, singleProjectMode, database, hosting, dataconnect, apphosting.

firenook init --adopt --dry-run runs every check on a project and lists what it would add, without changing anything.

Entry What Firenook does with it
projects.default The project id when nothing else names one
projects.<alias> An alias --project can name
targets.<project>.storage.<target> The buckets of a Storage target

firenook use, target:apply and target:clear edit these entries. Other target types, such as hosting, are not read.

A project id is lowercase letters, digits and hyphens, 6 to 30 characters, starting with a letter, or any id that starts with demo-. A demo- id never reaches a real Firebase project. With any other id, Firenook starts every Functions worker with the emulators’ addresses and no Google credentials, but your functions are your code and can still call outside services. Firenook is not a network sandbox.

Firenook picks the project as the official CLI does, the first of:

  1. --project (or -P);
  2. the project firebase use chose for this folder or a folder above it, which the Firebase CLI keeps in configstore/firebase-tools.json under $XDG_CONFIG_HOME, else ~/.config;
  3. the legacy firebase key of firebase.json;
  4. .firebaserc: its only alias, or projects.default.

A choice that names an alias selects that alias, and with it the codebase’s .env.<alias> file. Firenook only reads the Firebase CLI’s file, and never writes it.

Each codebase reads the official chain of .env files from its configDir, later files winning: .env, .env.<projectId>, .env.<alias> and .env.local. The alias is the one the project was chosen by: dev for --project dev or firebase use dev, when dev is an alias, and otherwise .firebaserc’s only alias, or default. A project named by its id has no alias. Having both .env.<projectId> and .env.<alias> is refused, as officially. The start says which files it loaded:

firenook functions: Loaded environment variables from .env, .env.dev.

Params take their value from those files, else their default, also in the function’s options such as region or memory. A param with neither stops its codebase, since Firenook never prompts. See Environment variables and secrets.

Your functions run on the Node that runs Firenook: 22, 24 or 26. A codebase whose functions.runtime or engines.node asks for another Node starts with a warning, as in the official emulator:

firenook functions: functions/package.json asks for Node 22 in engines.node, but these functions run on Node 24.20.0, the Node running the emulators; start the emulators with Node 22 to run them on the Node they ask for (with nvm: nvm use 22)

In a terminal it is one of the start-up warnings that w lists. A range in engines.node, such as >=22, is read as npm reads it.

Variable Effect
FIRENOOK_PLAIN=1 Plain lines instead of the terminal screen
CI Plain lines, and no release check
TERM dumb gives plain lines; linux gives plain characters instead of symbols; a name with 256 gives 256 colours
COLORTERM truecolor or 24bit gives 24-bit colour
NO_COLOR Set to anything, it keeps the screen and drops the colours
FIRENOOK_ASCII=1 Plain characters instead of symbols, and no clickable links
WT_SESSION Set by Windows Terminal; without it, the Windows console gets plain characters
FIRENOOK_NO_UPDATE_CHECK=1 No release check
NO_UPDATE_NOTIFIER=1 No release check
XDG_CACHE_HOME, LOCALAPPDATA Where the release check keeps its last answer, in firenook/update-check.json. Defaults: ~/Library/Caches on macOS, %LOCALAPPDATA% on Windows, ~/.cache elsewhere

FIRENOOK_PLAIN, FIRENOOK_ASCII, CI, FIRENOOK_NO_UPDATE_CHECK and NO_UPDATE_NOTIFIER count as set unless they are empty, 0 or false, so CI=false is not CI.

Variable Effect
FIRENOOK_OFFLINE 1 or true works as --offline: the Extensions registry is never contacted
FIREBASE_TOKEN The credential used to fetch an Extension from the registry, on first use only. Without it, Firenook uses the Firebase CLI’s stored login. It is never passed to your functions.
XDG_CONFIG_HOME Where Firenook looks for the Firebase CLI’s stored login, configstore/firebase-tools.json, and the project firebase use chose. Default: .config in your home folder (%USERPROFILE% on Windows)
FIREBASE_EXTENSIONS_CACHE_PATH The shared cache of Extension sources. Default: ~/.cache/firebase/extensions
FIREBASE_EXT_URL, FIREBASE_TOKEN_URL, FIREBASE_GOOGLE_URL, FIREBASE_CLIENT_ID, FIREBASE_CLIENT_SECRET Override the registry and token endpoints, as they do for the Firebase CLI

firenook ext:vendor copies Extensions into the project so none of these is needed again. See Without a Google login.

Variable Effect
FUNCTIONS_DISCOVERY_TIMEOUT Seconds to wait while a codebase lists its functions. Default: 10
FIRENOOK_FIELD_INDEXES 0, off or false turns off Firestore’s field index, so queries scan and sort instead, for comparison. The next start without it builds the index again.
MIMALLOC_PURGE_DELAY, MIMALLOC_PURGE_DECOMMITS The engine’s memory allocator settings. Firenook sets them to 100 and 1 unless you set them
FIRENOOK_LOCATOR_DIR Where the CLI commands look for hub-<project>.json files instead of the system’s temporary folder. Meant for tests; the engine still writes its file to the temporary folder

Firenook starts the engine with GCLOUD_PROJECT and GOOGLE_CLOUD_PROJECT set to the project id, demo credentials of the run’s own in GOOGLE_APPLICATION_CREDENTIALS, and a gcloud folder of the run’s own in CLOUDSDK_CONFIG, so the gcloud configuration of your machine is not used. It removes CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE.

The command of emulators:exec gets the official variables, for each emulator that runs and for no other, so the Admin SDKs and Google Cloud clients find the emulators by themselves:

Variable Value Set when
FIRESTORE_EMULATOR_HOST, FIREBASE_FIRESTORE_EMULATOR_ADDRESS 127.0.0.1:8080 Firestore runs
FIREBASE_AUTH_EMULATOR_HOST 127.0.0.1:9099 Auth runs
FIREBASE_STORAGE_EMULATOR_HOST 127.0.0.1:9199 Storage runs
STORAGE_EMULATOR_HOST http://127.0.0.1:9199 Storage runs
PUBSUB_EMULATOR_HOST 127.0.0.1:8085 Pub/Sub runs
CLOUD_TASKS_EMULATOR_HOST 127.0.0.1:9499 Functions runs
CLOUD_EVENTARC_EMULATOR_HOST http://127.0.0.1:9299 Functions runs
FIREBASE_EMULATOR_HUB 127.0.0.1:4400 Always
GCLOUD_PROJECT, GOOGLE_CLOUD_PROJECT The project id Always
FIREBASE_CONFIG {"projectId": ..., "storageBucket": ..., "databaseURL": ...} for the project Unless you set it
GOOGLE_APPLICATION_CREDENTIALS A demo authorized_user file in the run’s folder, whose token address is the hub Unless you set it
CLOUDSDK_CONFIG A gcloud folder of the run’s own Always
NODE_OPTIONS Yours, then --require of the CLI’s exec-token.cjs, which answers a Node.js Admin SDK’s token request with the emulators’ token Unless you set GOOGLE_APPLICATION_CREDENTIALS

The values follow your ports, and the address clients can connect to: 127.0.0.1 for the default localhost and for 0.0.0.0, and ::1 for ::. With your own GOOGLE_APPLICATION_CREDENTIALS, exec passes it on unchanged, as the official emulators:exec does, and says so: a call that needs an access token then gets one with your credentials, from Google. Your functions get the emulators’ variables too, with demo credentials that are never yours; see Environment variables and secrets.

Ports lists every listener with its default, its firebase.json key and its flag.