{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/hnrss-org/2026-11-05-show-hn-firenook-firebase-emulators-in-rust-40x-faster/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "[0.2.1 What’s new](https://firenook.dev/changelog/0.2.1)\n\n## A faster drop-in replacement for the Firebase Local Emulator Suite\n\nKeep your `firebase.json`, SDKs and ports, and change one word in your script. No Java to install, and your data survives restarts.\n\n40×\n\nfaster writes 5.1 ms against 208.2 ms, median\n\n10×\n\nless memory 2.11 GiB against 22.57 GiB at peak\n\n0.59 s\n\nto restart with your data against 30.8 s\n\n```\n  ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮\n  │                                                                                                      │\n  │       ▄█                                                                                             │\n  │    ▄███▀ ▄     firenook  0.2.0                                                                       │\n  │  ▄███▀ ███▄    demo-shop · picking up the data saved just now                                        │\n  │  ▀██▀ ███▀     Node 24.20.0 · data in .firenook/state                                                │\n  │      █▀▀                                                                                             │\n  │                                                                                                      │\n  ├─ Start-up ────────────────────────────────────────────────────────────────────────────────── 796 ms ─┤\n  │                                                                                                      │\n  │  Firestore   ✓ 255 ms  1,207,802 documents                                                           │\n  │  Auth        ✓ 255 ms  64,000 users                                                                  │\n  │  Storage     ✓ 255 ms  5,400 objects                                                                 │\n  │  Functions   ✓ 423 ms  4 functions                                                                   │\n  │  Pub/Sub     ✓   0 ms  1 schedule                                                                    │\n  │                                                                                                      │\n  ├─ ✓ All emulators ready ──────────────────────────────────────────────────────────────────────────────┤\n  │                                                                                                      │\n  │  Console       http://127.0.0.1:4000/console                                                         │\n  │  Ports         Firestore 8080   Auth 9099   Storage 9199   Functions 5001   Pub/Sub 8085   Hub 4400  │\n  │                                                                                                      │\n  ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯\n\n  ── Logs ────────────────────────────────────────────────────────────────────────────────────────────────\n\n     21:05:40    ✓ checkout        117 ms  http · POST / · 201\n     21:05:40    ✓ sendReceipt       6 ms  firestore · orders/qXoV1oOgJ0IILQs5psZP created\n                 │ receipt queued   order qXoV1oOgJ0IILQs5psZP · total 36\n     21:05:42    ✓ checkout          4 ms  http · POST / · 201\n     21:05:42    ✓ sendReceipt       1 ms  firestore · orders/ZskDC6u3kTKSGalf4o5L created\n                 │ receipt queued   order ZskDC6u3kTKSGalf4o5L · total 32\n     21:05:43    ✕ stripeWebhook     1 ms  http · POST / · 500\n                 │ Unhandled error Error: No signatures found matching the expected signature for payload\n                 │   at functions/index.js:24:11\n                 │ + 9 more lines · open in console\n\n\n  ────────────────────────────────────────────────────────────────────────────────────────────────────────\n     ● running 6s · 5 calls · 1 failed                              o console   r reload   ? keys   q quit\n```\n\n```\n  ╭────────────────────────────────────────────────────────────╮\n  │                                                            │\n  │       ▄█                                                   │\n  │    ▄███▀ ▄     firenook  0.2.0                             │\n  │  ▄███▀ ███▄    demo-shop · picking up the data saved jus…  │\n  │  ▀██▀ ███▀     Node 24.20.0 · data in .firenook/state      │\n  │      █▀▀                                                   │\n  │                                                            │\n  ├─ Start-up ──────────────────────────────────────── 602 ms ─┤\n  │                                                            │\n  │  Firestore   ✓ 240 ms  1,207,804 documents                 │\n  │  Auth        ✓ 240 ms  64,000 users                        │\n  │  Storage     ✓ 240 ms  5,400 objects                       │\n  │  Functions   ✓ 299 ms  4 functions                         │\n  │  Pub/Sub     ✓   0 ms  1 schedule                          │\n  │                                                            │\n  ├─ ✓ All emulators ready ────────────────────────────────────┤\n  │                                                            │\n  │  Console       http://127.0.0.1:4000/console               │\n  │  Ports         Firestore 8080   Auth 9099   Storage 9199   │\n  │                Functions 5001   Pub/Sub 8085   Hub 4400    │\n  │                                                            │\n  ╰────────────────────────────────────────────────────────────╯\n\n  ── Logs ──────────────────────────────────────────────────────\n\n     21:05:49    ✓ checkout        115 ms  http · POST / · 201\n     21:05:49    ✓ sendReceipt       6 ms  firestore · orders/E…\n                 │ receipt queued\n                 │ order EYi9LKG7xQ53eLrWktHm · total 36\n     21:05:50    ✓ checkout          6 ms  http · POST / · 201\n     21:05:50    ✓ sendReceipt       2 ms  firestore · orders/C…\n                 │ receipt queued\n                 │ order CU0LwsLgczq054BqsEuH · total 32\n     21:05:51    ✕ stripeWebhook     1 ms  http · POST / · 500\n                 │ Unhandled error Error: No signatures found\n                 │ matching the expected signature for payload\n                 │   at functions/index.js:24:11\n                 │ + 9 more lines · open in console\n\n\n  ──────────────────────────────────────────────────────────────\n     ● running 6s · 5 calls · 1 failed\n     o console   r reload   ? keys   q quit\n```\n\n```\n$ npx firebase emulators:start\n```\n\nFirenook’s own screen, recorded from 0.2.0 on a demo shop: it starts with the 1.2 million documents, 64,000 users and 5,400 files it kept from its last run, takes two orders, and shows a webhook that fails, with its stack trace.\n\n## Change one word\n\nSame flags, same ports, same export format. Your project stays as it is, and firebase-tools stays for deploying.\n\npackage.json\n\n```\n-  \"emulators\": \"firebase emulators:start --import ./data\"+  \"emulators\": \"firenook emulators:start --import ./data\"\n```\n\n- ### firebase.json and .firebaserc\n\n  Read the way the Firebase CLI reads them.\n\n- ### Rules, indexes, Functions\n\n  Your code and config stay as they are.\n\n- ### Your SDKs\n\n  connectFirestoreEmulator, FIRESTORE\\_EMULATOR\\_HOST and the rest connect unchanged.\n\n- ### Your data\n\n  Imports and exports the official format, both ways.\n\n## Eight emulators, on the ports you already use\n\nYour SDKs connect to them as they connect to Google’s: the same hosts, the same ports, the same environment variables.\n\n### [Firestore](https://firenook.dev/firestore-emulator)\n\n8080\n\nNative and web SDKs, realtime listeners, Security Rules, named databases, and the official import and export.\n\norders 12 documents\n\n- XXfs8ZLaWvmMOeaVAcw8\n- 5XSNbW90qkxiTbqQilu1\n- mqr7wc5Vjb6d5y75tfKy\n- ijO11GokICQ0ki9Ta4p9\n- c0yT9Jkt9NGpiX7HMV9r\n\ncreatedAt\n\n2026-10-23 13:06:17.872 UTC\n\nitems\n\n\\[{ price: 54, qty: 1, sku: \"hoodie\" }, { price: 28, qty: 1, sku: \"tee\" }\\]\n\ntotal\n\n82\n\n### [Authentication](https://firenook.dev/compatibility#auth)\n\n9099\n\nEvery operation of the official Auth emulator: password, email link, phone, MFA, passkeys, tenants and blocking functions.\n\nUsers 12\n\n- Amara Abara amara@example.com password\n- Elif Demir elif@example.com password\n- Ines Duarte ines@example.com password\n\n### [Cloud Storage](https://firenook.dev/compatibility#storage)\n\n9199\n\nThe Firebase and Cloud Storage APIs, with Security Rules evaluated natively, `firestore.get()` included.\n\ndemo-shop.appspot.com / products 8 files\n\n- cap.svg image/svg+xml 404 B\n- hoodie.svg image/svg+xml 408 B\n- mug.svg image/svg+xml 404 B\n\n### [Cloud Functions](https://firenook.dev/compatibility#functions)\n\n5001\n\nHTTP, callable and streaming functions, and every trigger: Firestore, Storage, Auth, Pub/Sub, Eventarc, schedules and task queues. Code reloads on save.\n\nFunction calls 25\n\n| Time     | Function      | Trigger   | Summary                             | Status | Duration |\n| -------- | ------------- | --------- | ----------------------------------- | ------ | -------- |\n| 13:06:19 | stripeWebhook | http      | POST /                              | 500    | 1.1 ms   |\n| 13:06:18 | sendReceipt   | firestore | orders/mzbnHY1n79leG5ioi2nD created | 200    | 1.8 ms   |\n| 13:06:18 | checkout      | http      | POST /                              | 201    | 6.3 ms   |\n| 13:06:18 | sendReceipt   | firestore | orders/c0yT9Jkt9NGpiX7HMV9r created | 200    | 1.7 ms   |\n| 13:06:18 | checkout      | http      | POST /                              | 201    | 5.0 ms   |\n\n### [Pub/Sub](https://firenook.dev/pubsub-emulator)\n\n8085\n\nEvery RPC over gRPC and HTTP/JSON: push, ordering, filters, dead-letter topics, seek, snapshots and schemas.\n\nnightlyReport, every day 02:00: next run 2026-10-24 02:00 UTC\n\n### [Cloud Tasks](https://firenook.dev/compatibility#tasks)\n\n9499\n\nQueues for onTaskDispatched, with the official retry and rate-limit behaviour.\n\n### [Eventarc](https://firenook.dev/compatibility#eventarc)\n\n9299\n\nCustom events delivered to onCustomEventPublished, and the Firebase services’ own.\n\n### [Extensions](https://firenook.dev/compatibility#extensions)\n\n5001\n\nExtensions from local, vendored or registry sources, offline once vendored.\n\nThe orders, users, files and calls above are from a run of the demo project, as Firenook returned them. Realtime Database, Hosting, App Hosting and Data Connect are not emulated; a `firebase.json` that configures them still starts, with a warning. [What each service covers](https://firenook.dev/compatibility).\n\n## Measured on a real application\n\nTwo hours of a production app’s traffic against each emulator in turn, every operation timed by the client.\n\n### Memory at peak\n\n10× less\n\nOfficial\n\n22.6 GiB\n\nFirenook\n\n2.11 GiB\n\n### Write, median\n\n40× faster\n\nOfficial\n\n208 ms\n\nFirenook\n\n5.1 ms\n\n### Listener update, median\n\n19× faster\n\nOfficial\n\n209 ms\n\nFirenook\n\n11 ms\n\n### Restart with data kept\n\n52× sooner\n\nOfficial\n\n30.8 s\n\nFirenook\n\n0.59 s\n\n### orderBy, limit 20\n\n8× faster\n\nOfficial\n\n96.3 ms\n\nFirenook\n\n12.0 ms\n\n### CPU over two hours\n\n61% less\n\nOfficial\n\n1,586 s\n\nFirenook\n\n616 s\n\nThe app holds 211,205 Firestore documents and 6.7 GB in Storage; both emulators ran on one server. Firenook answered 25 of 26 query shapes faster and tied on the last. [How it was measured](https://firenook.dev/benchmarks).\n\n## Your data stays where you left it\n\nAdd `--keep-data` and Firestore, Auth and Storage come back with all your data in about half a second, even with millions of documents. No export at every stop, no import at every start.\n\nA crash loses at most the last second of writes, where the official emulator loses everything since its last export. A stop always closes the data cleanly.\n\n`npx firenook emulators:start --keep-data`\n\nOfficial emulator\n\nStop: export, 50–57 s Start: import, 21.6–23.6 s\n\nFirenook\n\nStop, 0.04–0.30 s Start, 0.54–0.57 s\n\nStopping with the data saved, then starting again with it, on one time scale. The dim blocks are the spread between the fastest and the slowest runs.\n\n```\n$ npx firenook emulators:exec \"node --test checkout.test.mjs\"\nfirenook: Starting emulators: auth, functions, firestore, pubsub, storagefirenook functions: Loaded functions definitions from source: checkout, sendReceipt, stripeWebhook, nightlyReport.All emulators ready✔ checkout takes an order (173.227708ms)ℹ pass 1ℹ fail 0firenook suite stopped cleanly\n```\n\nexit 0 **1.39 s** from start to stop, the test included\n\nA run of the demo project’s test through firenook emulators:exec on firenook 0.2.0, with some lines left out.\n\n## Run your tests against it\n\n`emulators:exec` starts the suite, runs your command once everything is ready, with the emulator variables set, then stops and passes on the exit code.\n\nCI gets plain lines, the same ones the official emulator prints, and there is no Java to set up first. Firenook needs only Node 24.\n\n`npx firenook emulators:exec \"npm test\"`\n\n## The console the Firebase emulators should have had\n\nGoogle’s Emulator UI has no page for your Functions, Pub/Sub, Cloud Tasks or Eventarc, only a log. Firenook’s console covers every service it runs, live, on the Emulator UI’s port.\n\nEvery call, with what triggered it, its outcome, its duration and its logs.\n\n![The console’s function calls: every call with its time, function, trigger, summary, outcome and duration, one of them a 500](https://firenook.dev/_astro/invocations-dark.CWGnqWbs_jxCnL.webp)\n\nLight and dark, works offline, sends nothing anywhere. Bookmarks to the official UI’s pages open the matching console page. [Every page of the console](https://firenook.dev/console).\n\n## Give your agent the emulator, not production\n\n`firenook mcp` gives a coding agent 54 tools over the running suite. It reads the log and each function call with its error, asks the Security Rules why a request is denied, and works with your data. Nothing leaves your machine.\n\n`npx firenook mcp add`\n\nSets it up for Claude Code, Cursor and VS Code in the project’s own files. Other agents run `npx firenook mcp`. [How agents use it](https://firenook.dev/mcp).\n\n1. You\n\n   The Stripe webhook answers 500 on my machine. Why?\n\n2. **functions\\_list\\_calls** outcome: \"failed\"\n\n   failed\n\n   500 stripeWebhook http POST /, 1.15 ms at 13:06:19\n\n3. **functions\\_get\\_call** id: \"e72ca3-25\"\n\n   error\n\n   Error: No signatures found matching the expected signature for payload\n\n   at\n\n   functions/index.js:24:11\n\n   headers\n\n   host, connection, content-type, accept, accept-language, sec-fetch-mode, user-agent, accept-encoding, content-length\n\n   body\n\n   {\"type\":\"checkout.session.completed\"}\n\n4. **rules\\_evaluate** service: \"storage\", method: \"create\", path: \"products/mug.svg\"\n\n   verdict\n\n   deny as unauthenticated\n\n   line 9\n\n   allow read, write: if false;\n\nThe question is an example. The tool calls and their answers are from a run of the demo project on firenook 0.2.0, as Firenook gave them.\n\nFirestore\n\nRead, query, count, write and delete documents\n\nAuthentication\n\nManage users, read sign-in codes, mint ID tokens, set claims\n\nStorage\n\nList, read, upload, copy, move and delete files\n\nFunctions and logs\n\nInvoke a function, read each call and the log, replay a call after a fix\n\nSecurity Rules\n\nAsk why a request is denied, test a draft, list denials\n\nPub/Sub, Tasks, Eventarc\n\nPublish, peek, run tasks and schedules now, replay events\n\nDo I still need firebase-tools?\n\nYes, for deploying and everything else the Firebase CLI does. Firenook replaces only the emulators: install it next to firebase-tools and run your emulators with it.\n\nDoes Firenook need Java?\n\nNo. Its services are native code in one npm package, with an engine for macOS, Linux and Windows, and nothing else is downloaded at install or start. Node 22, 24 or 26 runs your Functions, as it does in production.\n\nCan I go back to the official emulator?\n\nYes. Firenook imports and exports the official format. While Firenook runs, export with npx firenook emulators:export ./export, then start the official emulator with --import ./export.\n\nWhich services does it emulate?\n\nFirestore, Authentication, Cloud Storage, Cloud Functions, Extensions, Pub/Sub, Cloud Tasks and Eventarc. Realtime Database, Hosting, App Hosting and Data Connect are not emulated; a firebase.json that configures them still starts, with a warning.\n\nIs it ready for my team?\n\n0.2.0 is the first release for public use. Every release passes conformance replays against the official emulator and packed installs on all five platforms, and Firenook passed a two-hour benchmark against the official emulator on a real application. Commit your lockfile and upgrade on purpose.\n\nIs it free?\n\nYes. Firenook is open source under the Apache License 2.0.\n\nIs Firenook made by Google?\n\nNo. Firenook is an independent open-source project, not affiliated with or endorsed by Google. Firebase is a trademark of Google LLC.\n\n## Switch in three steps\n\nOne package, nothing else to install: Node 22, 24 or 26 on macOS, Linux with glibc 2.28 or newer, or Windows x64. Starting a new project instead? `npx firenook init` sets one up.\n\n1. ### Install it next to firebase-tools\n\n   Keep firebase-tools for deploying: Firenook has no deploy or login command.\n\n   `npm install --save-dev firenook`\n\n2. ### Check your project\n\n   This reads firebase.json the way the Firebase CLI does, and changes nothing.\n\n   `npx firenook init --adopt --dry-run`\n\n3. ### Swap the command\n\n   Same flags and ports, so your app connects as before and your data imports as it is.\n\n   `npx firenook emulators:start`\n",
  "authors": [
    "sanjevirau"
  ],
  "captured_at": "2026-11-06T11:27:16.888185679+00:00",
  "category": "news",
  "content_html": "<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/changelog/0.2.1\">0.2.1 What’s new</a></p>\n<h2>A faster drop-in replacement for the Firebase Local Emulator Suite</h2>\n<p>Keep your <code>firebase.json</code>, SDKs and ports, and change one word in your script. No Java to install, and your data survives restarts.</p>\n<p>40×</p>\n<p>faster writes 5.1 ms against 208.2 ms, median</p>\n<p>10×</p>\n<p>less memory 2.11 GiB against 22.57 GiB at peak</p>\n<p>0.59 s</p>\n<p>to restart with your data against 30.8 s</p>\n<pre><code><span class=\"code-snippet\">  ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮\n  │                                                                                                      │\n  │       ▄█                                                                                             │\n  │    ▄███▀ ▄     firenook  0.2.0                                                                       │\n  │  ▄███▀ ███▄    demo-shop · picking up the data saved just now                                        │\n  │  ▀██▀ ███▀     Node 24.20.0 · data in .firenook/state                                                │\n  │      █▀▀                                                                                             │\n  │                                                                                                      │\n  ├─ Start-up ────────────────────────────────────────────────────────────────────────────────── 796 ms ─┤\n  │                                                                                                      │\n  │  Firestore   ✓ 255 ms  1,207,802 documents                                                           │\n  │  Auth        ✓ 255 ms  64,000 users                                                                  │\n  │  Storage     ✓ 255 ms  5,400 objects                                                                 │\n  │  Functions   ✓ 423 ms  4 functions                                                                   │\n  │  Pub/Sub     ✓   0 ms  1 schedule                                                                    │\n  │                                                                                                      │\n  ├─ ✓ All emulators ready ──────────────────────────────────────────────────────────────────────────────┤\n  │                                                                                                      │\n  │  Console       http://127.0.0.1:4000/console                                                         │\n  │  Ports         Firestore 8080   Auth 9099   Storage 9199   Functions 5001   Pub/Sub 8085   Hub 4400  │\n  │                                                                                                      │\n  ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯\n\n  ── Logs ────────────────────────────────────────────────────────────────────────────────────────────────\n\n     21:05:40    ✓ checkout        117 ms  http · POST / · 201\n     21:05:40    ✓ sendReceipt       6 ms  firestore · orders/qXoV1oOgJ0IILQs5psZP created\n                 │ receipt queued   order qXoV1oOgJ0IILQs5psZP · total 36\n     21:05:42    ✓ checkout          4 ms  http · POST / · 201\n     21:05:42    ✓ sendReceipt       1 ms  firestore · orders/ZskDC6u3kTKSGalf4o5L created\n                 │ receipt queued   order ZskDC6u3kTKSGalf4o5L · total 32\n     21:05:43    ✕ stripeWebhook     1 ms  http · POST / · 500\n                 │ Unhandled error Error: No signatures found matching the expected signature for payload\n                 │   at functions/index.js:24:11\n                 │ + 9 more lines · open in console\n\n\n  ────────────────────────────────────────────────────────────────────────────────────────────────────────\n     ● running 6s · 5 calls · 1 failed                              o console   r reload   ? keys   q quit\n</span></code></pre>\n<pre><code><span class=\"code-snippet\">  ╭────────────────────────────────────────────────────────────╮\n  │                                                            │\n  │       ▄█                                                   │\n  │    ▄███▀ ▄     firenook  0.2.0                             │\n  │  ▄███▀ ███▄    demo-shop · picking up the data saved jus…  │\n  │  ▀██▀ ███▀     Node 24.20.0 · data in .firenook/state      │\n  │      █▀▀                                                   │\n  │                                                            │\n  ├─ Start-up ──────────────────────────────────────── 602 ms ─┤\n  │                                                            │\n  │  Firestore   ✓ 240 ms  1,207,804 documents                 │\n  │  Auth        ✓ 240 ms  64,000 users                        │\n  │  Storage     ✓ 240 ms  5,400 objects                       │\n  │  Functions   ✓ 299 ms  4 functions                         │\n  │  Pub/Sub     ✓   0 ms  1 schedule                          │\n  │                                                            │\n  ├─ ✓ All emulators ready ────────────────────────────────────┤\n  │                                                            │\n  │  Console       http://127.0.0.1:4000/console               │\n  │  Ports         Firestore 8080   Auth 9099   Storage 9199   │\n  │                Functions 5001   Pub/Sub 8085   Hub 4400    │\n  │                                                            │\n  ╰────────────────────────────────────────────────────────────╯\n\n  ── Logs ──────────────────────────────────────────────────────\n\n     21:05:49    ✓ checkout        115 ms  http · POST / · 201\n     21:05:49    ✓ sendReceipt       6 ms  firestore · orders/E…\n                 │ receipt queued\n                 │ order EYi9LKG7xQ53eLrWktHm · total 36\n     21:05:50    ✓ checkout          6 ms  http · POST / · 201\n     21:05:50    ✓ sendReceipt       2 ms  firestore · orders/C…\n                 │ receipt queued\n                 │ order CU0LwsLgczq054BqsEuH · total 32\n     21:05:51    ✕ stripeWebhook     1 ms  http · POST / · 500\n                 │ Unhandled error Error: No signatures found\n                 │ matching the expected signature for payload\n                 │   at functions/index.js:24:11\n                 │ + 9 more lines · open in console\n\n\n  ──────────────────────────────────────────────────────────────\n     ● running 6s · 5 calls · 1 failed\n     o console   r reload   ? keys   q quit\n</span></code></pre>\n<pre><code><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">$</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> npx firebase emulators:start</span>\n</span></span></code></pre>\n<p>Firenook’s own screen, recorded from 0.2.0 on a demo shop: it starts with the 1.2 million documents, 64,000 users and 5,400 files it kept from its last run, takes two orders, and shows a webhook that fails, with its stack trace.</p>\n<h2>Change one word</h2>\n<p>Same flags, same ports, same export format. Your project stays as it is, and firebase-tools stays for deploying.</p>\n<p>package.json</p>\n<pre><code><span class=\"code-snippet\">-  &quot;emulators&quot;: &quot;firebase emulators:start --import ./data&quot;+  &quot;emulators&quot;: &quot;firenook emulators:start --import ./data&quot;\n</span></code></pre>\n<ul>\n<li>\n<h3>firebase.json and .firebaserc</h3>\n<p>Read the way the Firebase CLI reads them.</p>\n</li>\n<li>\n<h3>Rules, indexes, Functions</h3>\n<p>Your code and config stay as they are.</p>\n</li>\n<li>\n<h3>Your SDKs</h3>\n<p>connectFirestoreEmulator, FIRESTORE_EMULATOR_HOST and the rest connect unchanged.</p>\n</li>\n<li>\n<h3>Your data</h3>\n<p>Imports and exports the official format, both ways.</p>\n</li>\n</ul>\n<h2>Eight emulators, on the ports you already use</h2>\n<p>Your SDKs connect to them as they connect to Google’s: the same hosts, the same ports, the same environment variables.</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/firestore-emulator\">Firestore</a></h3>\n<p>8080</p>\n<p>Native and web SDKs, realtime listeners, Security Rules, named databases, and the official import and export.</p>\n<p>orders 12 documents</p>\n<ul>\n<li>XXfs8ZLaWvmMOeaVAcw8</li>\n<li>5XSNbW90qkxiTbqQilu1</li>\n<li>mqr7wc5Vjb6d5y75tfKy</li>\n<li>ijO11GokICQ0ki9Ta4p9</li>\n<li>c0yT9Jkt9NGpiX7HMV9r</li>\n</ul>\n<p>createdAt</p>\n<p>2026-10-23 13:06:17.872 UTC</p>\n<p>items</p>\n<p>[{ price: 54, qty: 1, sku: &quot;hoodie&quot; }, { price: 28, qty: 1, sku: &quot;tee&quot; }]</p>\n<p>total</p>\n<p>82</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/compatibility#auth\">Authentication</a></h3>\n<p>9099</p>\n<p>Every operation of the official Auth emulator: password, email link, phone, MFA, passkeys, tenants and blocking functions.</p>\n<p>Users 12</p>\n<ul>\n<li>Amara Abara <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"mailto:amara@example.com\">amara@example.com</a> password</li>\n<li>Elif Demir <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"mailto:elif@example.com\">elif@example.com</a> password</li>\n<li>Ines Duarte <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"mailto:ines@example.com\">ines@example.com</a> password</li>\n</ul>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/compatibility#storage\">Cloud Storage</a></h3>\n<p>9199</p>\n<p>The Firebase and Cloud Storage APIs, with Security Rules evaluated natively, <code>firestore.get()</code> included.</p>\n<p>demo-shop.appspot.com / products 8 files</p>\n<ul>\n<li>cap.svg image/svg+xml 404 B</li>\n<li>hoodie.svg image/svg+xml 408 B</li>\n<li>mug.svg image/svg+xml 404 B</li>\n</ul>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/compatibility#functions\">Cloud Functions</a></h3>\n<p>5001</p>\n<p>HTTP, callable and streaming functions, and every trigger: Firestore, Storage, Auth, Pub/Sub, Eventarc, schedules and task queues. Code reloads on save.</p>\n<p>Function calls 25</p>\n<table>\n<thead>\n<tr>\n<th>Time</th>\n<th>Function</th>\n<th>Trigger</th>\n<th>Summary</th>\n<th>Status</th>\n<th>Duration</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>13:06:19</td>\n<td>stripeWebhook</td>\n<td>http</td>\n<td>POST /</td>\n<td>500</td>\n<td>1.1 ms</td>\n</tr>\n<tr>\n<td>13:06:18</td>\n<td>sendReceipt</td>\n<td>firestore</td>\n<td>orders/mzbnHY1n79leG5ioi2nD created</td>\n<td>200</td>\n<td>1.8 ms</td>\n</tr>\n<tr>\n<td>13:06:18</td>\n<td>checkout</td>\n<td>http</td>\n<td>POST /</td>\n<td>201</td>\n<td>6.3 ms</td>\n</tr>\n<tr>\n<td>13:06:18</td>\n<td>sendReceipt</td>\n<td>firestore</td>\n<td>orders/c0yT9Jkt9NGpiX7HMV9r created</td>\n<td>200</td>\n<td>1.7 ms</td>\n</tr>\n<tr>\n<td>13:06:18</td>\n<td>checkout</td>\n<td>http</td>\n<td>POST /</td>\n<td>201</td>\n<td>5.0 ms</td>\n</tr>\n</tbody>\n</table>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/pubsub-emulator\">Pub/Sub</a></h3>\n<p>8085</p>\n<p>Every RPC over gRPC and HTTP/JSON: push, ordering, filters, dead-letter topics, seek, snapshots and schemas.</p>\n<p>nightlyReport, every day 02:00: next run 2026-10-24 02:00 UTC</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/compatibility#tasks\">Cloud Tasks</a></h3>\n<p>9499</p>\n<p>Queues for onTaskDispatched, with the official retry and rate-limit behaviour.</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/compatibility#eventarc\">Eventarc</a></h3>\n<p>9299</p>\n<p>Custom events delivered to onCustomEventPublished, and the Firebase services’ own.</p>\n<h3><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/compatibility#extensions\">Extensions</a></h3>\n<p>5001</p>\n<p>Extensions from local, vendored or registry sources, offline once vendored.</p>\n<p>The orders, users, files and calls above are from a run of the demo project, as Firenook returned them. Realtime Database, Hosting, App Hosting and Data Connect are not emulated; a <code>firebase.json</code> that configures them still starts, with a warning. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/compatibility\">What each service covers</a>.</p>\n<h2>Measured on a real application</h2>\n<p>Two hours of a production app’s traffic against each emulator in turn, every operation timed by the client.</p>\n<h3>Memory at peak</h3>\n<p>10× less</p>\n<p>Official</p>\n<p>22.6 GiB</p>\n<p>Firenook</p>\n<p>2.11 GiB</p>\n<h3>Write, median</h3>\n<p>40× faster</p>\n<p>Official</p>\n<p>208 ms</p>\n<p>Firenook</p>\n<p>5.1 ms</p>\n<h3>Listener update, median</h3>\n<p>19× faster</p>\n<p>Official</p>\n<p>209 ms</p>\n<p>Firenook</p>\n<p>11 ms</p>\n<h3>Restart with data kept</h3>\n<p>52× sooner</p>\n<p>Official</p>\n<p>30.8 s</p>\n<p>Firenook</p>\n<p>0.59 s</p>\n<h3>orderBy, limit 20</h3>\n<p>8× faster</p>\n<p>Official</p>\n<p>96.3 ms</p>\n<p>Firenook</p>\n<p>12.0 ms</p>\n<h3>CPU over two hours</h3>\n<p>61% less</p>\n<p>Official</p>\n<p>1,586 s</p>\n<p>Firenook</p>\n<p>616 s</p>\n<p>The app holds 211,205 Firestore documents and 6.7 GB in Storage; both emulators ran on one server. Firenook answered 25 of 26 query shapes faster and tied on the last. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/benchmarks\">How it was measured</a>.</p>\n<h2>Your data stays where you left it</h2>\n<p>Add <code>--keep-data</code> and Firestore, Auth and Storage come back with all your data in about half a second, even with millions of documents. No export at every stop, no import at every start.</p>\n<p>A crash loses at most the last second of writes, where the official emulator loses everything since its last export. A stop always closes the data cleanly.</p>\n<p><code>npx firenook emulators:start --keep-data</code></p>\n<p>Official emulator</p>\n<p>Stop: export, 50–57 s Start: import, 21.6–23.6 s</p>\n<p>Firenook</p>\n<p>Stop, 0.04–0.30 s Start, 0.54–0.57 s</p>\n<p>Stopping with the data saved, then starting again with it, on one time scale. The dim blocks are the spread between the fastest and the slowest runs.</p>\n<pre><code><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">$</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> npx firenook emulators:exec <span class=\"syntax-string syntax-quoted syntax-double syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell\">&quot;</span>node --test checkout.test.mjs<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell\">&quot;</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">firenook:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> Starting emulators: auth, functions, firestore, pubsub, storagefirenook functions: Loaded functions definitions from source: checkout, sendReceipt, stripeWebhook, nightlyReport.All emulators ready✔ checkout takes an order (173.227708ms</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">ℹ</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> pass 1ℹ fail 0firenook suite stopped cleanly</span>\n</span></span></code></pre>\n<p>exit 0 <strong>1.39 s</strong> from start to stop, the test included</p>\n<p>A run of the demo project’s test through firenook emulators:exec on firenook 0.2.0, with some lines left out.</p>\n<h2>Run your tests against it</h2>\n<p><code>emulators:exec</code> starts the suite, runs your command once everything is ready, with the emulator variables set, then stops and passes on the exit code.</p>\n<p>CI gets plain lines, the same ones the official emulator prints, and there is no Java to set up first. Firenook needs only Node 24.</p>\n<p><code>npx firenook emulators:exec &quot;npm test&quot;</code></p>\n<h2>The console the Firebase emulators should have had</h2>\n<p>Google’s Emulator UI has no page for your Functions, Pub/Sub, Cloud Tasks or Eventarc, only a log. Firenook’s console covers every service it runs, live, on the Emulator UI’s port.</p>\n<p>Every call, with what triggered it, its outcome, its duration and its logs.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://firenook.dev/_astro/invocations-dark.CWGnqWbs_jxCnL.webp\" alt=\"The console’s function calls: every call with its time, function, trigger, summary, outcome and duration, one of them a 500\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Light and dark, works offline, sends nothing anywhere. Bookmarks to the official UI’s pages open the matching console page. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/console\">Every page of the console</a>.</p>\n<h2>Give your agent the emulator, not production</h2>\n<p><code>firenook mcp</code> gives a coding agent 54 tools over the running suite. It reads the log and each function call with its error, asks the Security Rules why a request is denied, and works with your data. Nothing leaves your machine.</p>\n<p><code>npx firenook mcp add</code></p>\n<p>Sets it up for Claude Code, Cursor and VS Code in the project’s own files. Other agents run <code>npx firenook mcp</code>. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://firenook.dev/mcp\">How agents use it</a>.</p>\n<ol>\n<li>\n<p>You</p>\n<p>The Stripe webhook answers 500 on my machine. Why?</p>\n</li>\n<li>\n<p><strong>functions_list_calls</strong> outcome: &quot;failed&quot;</p>\n<p>failed</p>\n<p>500 stripeWebhook http POST /, 1.15 ms at 13:06:19</p>\n</li>\n<li>\n<p><strong>functions_get_call</strong> id: &quot;e72ca3-25&quot;</p>\n<p>error</p>\n<p>Error: No signatures found matching the expected signature for payload</p>\n<p>at</p>\n<p>functions/index.js:24:11</p>\n<p>headers</p>\n<p>host, connection, content-type, accept, accept-language, sec-fetch-mode, user-agent, accept-encoding, content-length</p>\n<p>body</p>\n<p>{&quot;type&quot;:&quot;checkout.session.completed&quot;}</p>\n</li>\n<li>\n<p><strong>rules_evaluate</strong> service: &quot;storage&quot;, method: &quot;create&quot;, path: &quot;products/mug.svg&quot;</p>\n<p>verdict</p>\n<p>deny as unauthenticated</p>\n<p>line 9</p>\n<p>allow read, write: if false;</p>\n</li>\n</ol>\n<p>The question is an example. The tool calls and their answers are from a run of the demo project on firenook 0.2.0, as Firenook gave them.</p>\n<p>Firestore</p>\n<p>Read, query, count, write and delete documents</p>\n<p>Authentication</p>\n<p>Manage users, read sign-in codes, mint ID tokens, set claims</p>\n<p>Storage</p>\n<p>List, read, upload, copy, move and delete files</p>\n<p>Functions and logs</p>\n<p>Invoke a function, read each call and the log, replay a call after a fix</p>\n<p>Security Rules</p>\n<p>Ask why a request is denied, test a draft, list denials</p>\n<p>Pub/Sub, Tasks, Eventarc</p>\n<p>Publish, peek, run tasks and schedules now, replay events</p>\n<p>Do I still need firebase-tools?</p>\n<p>Yes, for deploying and everything else the Firebase CLI does. Firenook replaces only the emulators: install it next to firebase-tools and run your emulators with it.</p>\n<p>Does Firenook need Java?</p>\n<p>No. Its services are native code in one npm package, with an engine for macOS, Linux and Windows, and nothing else is downloaded at install or start. Node 22, 24 or 26 runs your Functions, as it does in production.</p>\n<p>Can I go back to the official emulator?</p>\n<p>Yes. Firenook imports and exports the official format. While Firenook runs, export with npx firenook emulators:export ./export, then start the official emulator with --import ./export.</p>\n<p>Which services does it emulate?</p>\n<p>Firestore, Authentication, Cloud Storage, Cloud Functions, Extensions, Pub/Sub, Cloud Tasks and Eventarc. Realtime Database, Hosting, App Hosting and Data Connect are not emulated; a firebase.json that configures them still starts, with a warning.</p>\n<p>Is it ready for my team?</p>\n<p>0.2.0 is the first release for public use. Every release passes conformance replays against the official emulator and packed installs on all five platforms, and Firenook passed a two-hour benchmark against the official emulator on a real application. Commit your lockfile and upgrade on purpose.</p>\n<p>Is it free?</p>\n<p>Yes. Firenook is open source under the Apache License 2.0.</p>\n<p>Is Firenook made by Google?</p>\n<p>No. Firenook is an independent open-source project, not affiliated with or endorsed by Google. Firebase is a trademark of Google LLC.</p>\n<h2>Switch in three steps</h2>\n<p>One package, nothing else to install: Node 22, 24 or 26 on macOS, Linux with glibc 2.28 or newer, or Windows x64. Starting a new project instead? <code>npx firenook init</code> sets one up.</p>\n<ol>\n<li>\n<h3>Install it next to firebase-tools</h3>\n<p>Keep firebase-tools for deploying: Firenook has no deploy or login command.</p>\n<p><code>npm install --save-dev firenook</code></p>\n</li>\n<li>\n<h3>Check your project</h3>\n<p>This reads firebase.json the way the Firebase CLI does, and changes nothing.</p>\n<p><code>npx firenook init --adopt --dry-run</code></p>\n</li>\n<li>\n<h3>Swap the command</h3>\n<p>Same flags and ports, so your app connects as before and your data imports as it is.</p>\n<p><code>npx firenook emulators:start</code></p>\n</li>\n</ol>\n",
  "content_markdown": "[0.2.1 What’s new](https://firenook.dev/changelog/0.2.1)\n\n## A faster drop-in replacement for the Firebase Local Emulator Suite\n\nKeep your `firebase.json`, SDKs and ports, and change one word in your script. No Java to install, and your data survives restarts.\n\n40×\n\nfaster writes 5.1 ms against 208.2 ms, median\n\n10×\n\nless memory 2.11 GiB against 22.57 GiB at peak\n\n0.59 s\n\nto restart with your data against 30.8 s\n\n```\n  ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮\n  │                                                                                                      │\n  │       ▄█                                                                                             │\n  │    ▄███▀ ▄     firenook  0.2.0                                                                       │\n  │  ▄███▀ ███▄    demo-shop · picking up the data saved just now                                        │\n  │  ▀██▀ ███▀     Node 24.20.0 · data in .firenook/state                                                │\n  │      █▀▀                                                                                             │\n  │                                                                                                      │\n  ├─ Start-up ────────────────────────────────────────────────────────────────────────────────── 796 ms ─┤\n  │                                                                                                      │\n  │  Firestore   ✓ 255 ms  1,207,802 documents                                                           │\n  │  Auth        ✓ 255 ms  64,000 users                                                                  │\n  │  Storage     ✓ 255 ms  5,400 objects                                                                 │\n  │  Functions   ✓ 423 ms  4 functions                                                                   │\n  │  Pub/Sub     ✓   0 ms  1 schedule                                                                    │\n  │                                                                                                      │\n  ├─ ✓ All emulators ready ──────────────────────────────────────────────────────────────────────────────┤\n  │                                                                                                      │\n  │  Console       http://127.0.0.1:4000/console                                                         │\n  │  Ports         Firestore 8080   Auth 9099   Storage 9199   Functions 5001   Pub/Sub 8085   Hub 4400  │\n  │                                                                                                      │\n  ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯\n\n  ── Logs ────────────────────────────────────────────────────────────────────────────────────────────────\n\n     21:05:40    ✓ checkout        117 ms  http · POST / · 201\n     21:05:40    ✓ sendReceipt       6 ms  firestore · orders/qXoV1oOgJ0IILQs5psZP created\n                 │ receipt queued   order qXoV1oOgJ0IILQs5psZP · total 36\n     21:05:42    ✓ checkout          4 ms  http · POST / · 201\n     21:05:42    ✓ sendReceipt       1 ms  firestore · orders/ZskDC6u3kTKSGalf4o5L created\n                 │ receipt queued   order ZskDC6u3kTKSGalf4o5L · total 32\n     21:05:43    ✕ stripeWebhook     1 ms  http · POST / · 500\n                 │ Unhandled error Error: No signatures found matching the expected signature for payload\n                 │   at functions/index.js:24:11\n                 │ + 9 more lines · open in console\n\n\n  ────────────────────────────────────────────────────────────────────────────────────────────────────────\n     ● running 6s · 5 calls · 1 failed                              o console   r reload   ? keys   q quit\n```\n\n```\n  ╭────────────────────────────────────────────────────────────╮\n  │                                                            │\n  │       ▄█                                                   │\n  │    ▄███▀ ▄     firenook  0.2.0                             │\n  │  ▄███▀ ███▄    demo-shop · picking up the data saved jus…  │\n  │  ▀██▀ ███▀     Node 24.20.0 · data in .firenook/state      │\n  │      █▀▀                                                   │\n  │                                                            │\n  ├─ Start-up ──────────────────────────────────────── 602 ms ─┤\n  │                                                            │\n  │  Firestore   ✓ 240 ms  1,207,804 documents                 │\n  │  Auth        ✓ 240 ms  64,000 users                        │\n  │  Storage     ✓ 240 ms  5,400 objects                       │\n  │  Functions   ✓ 299 ms  4 functions                         │\n  │  Pub/Sub     ✓   0 ms  1 schedule                          │\n  │                                                            │\n  ├─ ✓ All emulators ready ────────────────────────────────────┤\n  │                                                            │\n  │  Console       http://127.0.0.1:4000/console               │\n  │  Ports         Firestore 8080   Auth 9099   Storage 9199   │\n  │                Functions 5001   Pub/Sub 8085   Hub 4400    │\n  │                                                            │\n  ╰────────────────────────────────────────────────────────────╯\n\n  ── Logs ──────────────────────────────────────────────────────\n\n     21:05:49    ✓ checkout        115 ms  http · POST / · 201\n     21:05:49    ✓ sendReceipt       6 ms  firestore · orders/E…\n                 │ receipt queued\n                 │ order EYi9LKG7xQ53eLrWktHm · total 36\n     21:05:50    ✓ checkout          6 ms  http · POST / · 201\n     21:05:50    ✓ sendReceipt       2 ms  firestore · orders/C…\n                 │ receipt queued\n                 │ order CU0LwsLgczq054BqsEuH · total 32\n     21:05:51    ✕ stripeWebhook     1 ms  http · POST / · 500\n                 │ Unhandled error Error: No signatures found\n                 │ matching the expected signature for payload\n                 │   at functions/index.js:24:11\n                 │ + 9 more lines · open in console\n\n\n  ──────────────────────────────────────────────────────────────\n     ● running 6s · 5 calls · 1 failed\n     o console   r reload   ? keys   q quit\n```\n\n```\n$ npx firebase emulators:start\n```\n\nFirenook’s own screen, recorded from 0.2.0 on a demo shop: it starts with the 1.2 million documents, 64,000 users and 5,400 files it kept from its last run, takes two orders, and shows a webhook that fails, with its stack trace.\n\n## Change one word\n\nSame flags, same ports, same export format. Your project stays as it is, and firebase-tools stays for deploying.\n\npackage.json\n\n```\n-  \"emulators\": \"firebase emulators:start --import ./data\"+  \"emulators\": \"firenook emulators:start --import ./data\"\n```\n\n- ### firebase.json and .firebaserc\n\n  Read the way the Firebase CLI reads them.\n\n- ### Rules, indexes, Functions\n\n  Your code and config stay as they are.\n\n- ### Your SDKs\n\n  connectFirestoreEmulator, FIRESTORE\\_EMULATOR\\_HOST and the rest connect unchanged.\n\n- ### Your data\n\n  Imports and exports the official format, both ways.\n\n## Eight emulators, on the ports you already use\n\nYour SDKs connect to them as they connect to Google’s: the same hosts, the same ports, the same environment variables.\n\n### [Firestore](https://firenook.dev/firestore-emulator)\n\n8080\n\nNative and web SDKs, realtime listeners, Security Rules, named databases, and the official import and export.\n\norders 12 documents\n\n- XXfs8ZLaWvmMOeaVAcw8\n- 5XSNbW90qkxiTbqQilu1\n- mqr7wc5Vjb6d5y75tfKy\n- ijO11GokICQ0ki9Ta4p9\n- c0yT9Jkt9NGpiX7HMV9r\n\ncreatedAt\n\n2026-10-23 13:06:17.872 UTC\n\nitems\n\n\\[{ price: 54, qty: 1, sku: \"hoodie\" }, { price: 28, qty: 1, sku: \"tee\" }\\]\n\ntotal\n\n82\n\n### [Authentication](https://firenook.dev/compatibility#auth)\n\n9099\n\nEvery operation of the official Auth emulator: password, email link, phone, MFA, passkeys, tenants and blocking functions.\n\nUsers 12\n\n- Amara Abara amara@example.com password\n- Elif Demir elif@example.com password\n- Ines Duarte ines@example.com password\n\n### [Cloud Storage](https://firenook.dev/compatibility#storage)\n\n9199\n\nThe Firebase and Cloud Storage APIs, with Security Rules evaluated natively, `firestore.get()` included.\n\ndemo-shop.appspot.com / products 8 files\n\n- cap.svg image/svg+xml 404 B\n- hoodie.svg image/svg+xml 408 B\n- mug.svg image/svg+xml 404 B\n\n### [Cloud Functions](https://firenook.dev/compatibility#functions)\n\n5001\n\nHTTP, callable and streaming functions, and every trigger: Firestore, Storage, Auth, Pub/Sub, Eventarc, schedules and task queues. Code reloads on save.\n\nFunction calls 25\n\n| Time     | Function      | Trigger   | Summary                             | Status | Duration |\n| -------- | ------------- | --------- | ----------------------------------- | ------ | -------- |\n| 13:06:19 | stripeWebhook | http      | POST /                              | 500    | 1.1 ms   |\n| 13:06:18 | sendReceipt   | firestore | orders/mzbnHY1n79leG5ioi2nD created | 200    | 1.8 ms   |\n| 13:06:18 | checkout      | http      | POST /                              | 201    | 6.3 ms   |\n| 13:06:18 | sendReceipt   | firestore | orders/c0yT9Jkt9NGpiX7HMV9r created | 200    | 1.7 ms   |\n| 13:06:18 | checkout      | http      | POST /                              | 201    | 5.0 ms   |\n\n### [Pub/Sub](https://firenook.dev/pubsub-emulator)\n\n8085\n\nEvery RPC over gRPC and HTTP/JSON: push, ordering, filters, dead-letter topics, seek, snapshots and schemas.\n\nnightlyReport, every day 02:00: next run 2026-10-24 02:00 UTC\n\n### [Cloud Tasks](https://firenook.dev/compatibility#tasks)\n\n9499\n\nQueues for onTaskDispatched, with the official retry and rate-limit behaviour.\n\n### [Eventarc](https://firenook.dev/compatibility#eventarc)\n\n9299\n\nCustom events delivered to onCustomEventPublished, and the Firebase services’ own.\n\n### [Extensions](https://firenook.dev/compatibility#extensions)\n\n5001\n\nExtensions from local, vendored or registry sources, offline once vendored.\n\nThe orders, users, files and calls above are from a run of the demo project, as Firenook returned them. Realtime Database, Hosting, App Hosting and Data Connect are not emulated; a `firebase.json` that configures them still starts, with a warning. [What each service covers](https://firenook.dev/compatibility).\n\n## Measured on a real application\n\nTwo hours of a production app’s traffic against each emulator in turn, every operation timed by the client.\n\n### Memory at peak\n\n10× less\n\nOfficial\n\n22.6 GiB\n\nFirenook\n\n2.11 GiB\n\n### Write, median\n\n40× faster\n\nOfficial\n\n208 ms\n\nFirenook\n\n5.1 ms\n\n### Listener update, median\n\n19× faster\n\nOfficial\n\n209 ms\n\nFirenook\n\n11 ms\n\n### Restart with data kept\n\n52× sooner\n\nOfficial\n\n30.8 s\n\nFirenook\n\n0.59 s\n\n### orderBy, limit 20\n\n8× faster\n\nOfficial\n\n96.3 ms\n\nFirenook\n\n12.0 ms\n\n### CPU over two hours\n\n61% less\n\nOfficial\n\n1,586 s\n\nFirenook\n\n616 s\n\nThe app holds 211,205 Firestore documents and 6.7 GB in Storage; both emulators ran on one server. Firenook answered 25 of 26 query shapes faster and tied on the last. [How it was measured](https://firenook.dev/benchmarks).\n\n## Your data stays where you left it\n\nAdd `--keep-data` and Firestore, Auth and Storage come back with all your data in about half a second, even with millions of documents. No export at every stop, no import at every start.\n\nA crash loses at most the last second of writes, where the official emulator loses everything since its last export. A stop always closes the data cleanly.\n\n`npx firenook emulators:start --keep-data`\n\nOfficial emulator\n\nStop: export, 50–57 s Start: import, 21.6–23.6 s\n\nFirenook\n\nStop, 0.04–0.30 s Start, 0.54–0.57 s\n\nStopping with the data saved, then starting again with it, on one time scale. The dim blocks are the spread between the fastest and the slowest runs.\n\n```\n$ npx firenook emulators:exec \"node --test checkout.test.mjs\"\nfirenook: Starting emulators: auth, functions, firestore, pubsub, storagefirenook functions: Loaded functions definitions from source: checkout, sendReceipt, stripeWebhook, nightlyReport.All emulators ready✔ checkout takes an order (173.227708ms)ℹ pass 1ℹ fail 0firenook suite stopped cleanly\n```\n\nexit 0 **1.39 s** from start to stop, the test included\n\nA run of the demo project’s test through firenook emulators:exec on firenook 0.2.0, with some lines left out.\n\n## Run your tests against it\n\n`emulators:exec` starts the suite, runs your command once everything is ready, with the emulator variables set, then stops and passes on the exit code.\n\nCI gets plain lines, the same ones the official emulator prints, and there is no Java to set up first. Firenook needs only Node 24.\n\n`npx firenook emulators:exec \"npm test\"`\n\n## The console the Firebase emulators should have had\n\nGoogle’s Emulator UI has no page for your Functions, Pub/Sub, Cloud Tasks or Eventarc, only a log. Firenook’s console covers every service it runs, live, on the Emulator UI’s port.\n\nEvery call, with what triggered it, its outcome, its duration and its logs.\n\n![The console’s function calls: every call with its time, function, trigger, summary, outcome and duration, one of them a 500](https://firenook.dev/_astro/invocations-dark.CWGnqWbs_jxCnL.webp)\n\nLight and dark, works offline, sends nothing anywhere. Bookmarks to the official UI’s pages open the matching console page. [Every page of the console](https://firenook.dev/console).\n\n## Give your agent the emulator, not production\n\n`firenook mcp` gives a coding agent 54 tools over the running suite. It reads the log and each function call with its error, asks the Security Rules why a request is denied, and works with your data. Nothing leaves your machine.\n\n`npx firenook mcp add`\n\nSets it up for Claude Code, Cursor and VS Code in the project’s own files. Other agents run `npx firenook mcp`. [How agents use it](https://firenook.dev/mcp).\n\n1. You\n\n   The Stripe webhook answers 500 on my machine. Why?\n\n2. **functions\\_list\\_calls** outcome: \"failed\"\n\n   failed\n\n   500 stripeWebhook http POST /, 1.15 ms at 13:06:19\n\n3. **functions\\_get\\_call** id: \"e72ca3-25\"\n\n   error\n\n   Error: No signatures found matching the expected signature for payload\n\n   at\n\n   functions/index.js:24:11\n\n   headers\n\n   host, connection, content-type, accept, accept-language, sec-fetch-mode, user-agent, accept-encoding, content-length\n\n   body\n\n   {\"type\":\"checkout.session.completed\"}\n\n4. **rules\\_evaluate** service: \"storage\", method: \"create\", path: \"products/mug.svg\"\n\n   verdict\n\n   deny as unauthenticated\n\n   line 9\n\n   allow read, write: if false;\n\nThe question is an example. The tool calls and their answers are from a run of the demo project on firenook 0.2.0, as Firenook gave them.\n\nFirestore\n\nRead, query, count, write and delete documents\n\nAuthentication\n\nManage users, read sign-in codes, mint ID tokens, set claims\n\nStorage\n\nList, read, upload, copy, move and delete files\n\nFunctions and logs\n\nInvoke a function, read each call and the log, replay a call after a fix\n\nSecurity Rules\n\nAsk why a request is denied, test a draft, list denials\n\nPub/Sub, Tasks, Eventarc\n\nPublish, peek, run tasks and schedules now, replay events\n\nDo I still need firebase-tools?\n\nYes, for deploying and everything else the Firebase CLI does. Firenook replaces only the emulators: install it next to firebase-tools and run your emulators with it.\n\nDoes Firenook need Java?\n\nNo. Its services are native code in one npm package, with an engine for macOS, Linux and Windows, and nothing else is downloaded at install or start. Node 22, 24 or 26 runs your Functions, as it does in production.\n\nCan I go back to the official emulator?\n\nYes. Firenook imports and exports the official format. While Firenook runs, export with npx firenook emulators:export ./export, then start the official emulator with --import ./export.\n\nWhich services does it emulate?\n\nFirestore, Authentication, Cloud Storage, Cloud Functions, Extensions, Pub/Sub, Cloud Tasks and Eventarc. Realtime Database, Hosting, App Hosting and Data Connect are not emulated; a firebase.json that configures them still starts, with a warning.\n\nIs it ready for my team?\n\n0.2.0 is the first release for public use. Every release passes conformance replays against the official emulator and packed installs on all five platforms, and Firenook passed a two-hour benchmark against the official emulator on a real application. Commit your lockfile and upgrade on purpose.\n\nIs it free?\n\nYes. Firenook is open source under the Apache License 2.0.\n\nIs Firenook made by Google?\n\nNo. Firenook is an independent open-source project, not affiliated with or endorsed by Google. Firebase is a trademark of Google LLC.\n\n## Switch in three steps\n\nOne package, nothing else to install: Node 22, 24 or 26 on macOS, Linux with glibc 2.28 or newer, or Windows x64. Starting a new project instead? `npx firenook init` sets one up.\n\n1. ### Install it next to firebase-tools\n\n   Keep firebase-tools for deploying: Firenook has no deploy or login command.\n\n   `npm install --save-dev firenook`\n\n2. ### Check your project\n\n   This reads firebase.json the way the Firebase CLI does, and changes nothing.\n\n   `npx firenook init --adopt --dry-run`\n\n3. ### Swap the command\n\n   Same flags and ports, so your app connects as before and your data imports as it is.\n\n   `npx firenook emulators:start`\n",
  "dateCreated": "2026-11-06T11:27:16.888185679+00:00",
  "date_created": "2026-11-05T13:07:29+00:00",
  "date_modified": "2026-11-05T13:07:29+00:00",
  "date_published": "2026-11-05T13:07:29+00:00",
  "description": "Hi HN, we have been developing with Firebase for a long time, and the only way Firebase developers can build apps without directly costing them is using the official Firebase Emulator Suite. However, the issue with this suite is, it's…",
  "external_url": "https://firenook.dev/",
  "git": {
    "commit": "20068632b65d2830a2d54f25ca1d90d697bea2c0",
    "path": "items/hnrss-org/2026/11/2026-11-05-show-hn-firenook-firebase-emulators-in-rust-40x-faster.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/20068632b65d2830a2d54f25ca1d90d697bea2c0/items/hnrss-org/2026/11/2026-11-05-show-hn-firenook-firebase-emulators-in-rust-40x-faster.md"
  },
  "id": "urn:aggr:item:4693dec025465067d70b3e248c4725fb5155ed10",
  "isBasedOn": {
    "@id": "https://firenook.dev/"
  },
  "mainEntity": {
    "@id": "https://firenook.dev/",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/hnrss-org/2026-11-05-show-hn-firenook-firebase-emulators-in-rust-40x-faster/#webpage"
    },
    "author": [
      {
        "@type": "Person",
        "name": "sanjevirau"
      }
    ],
    "dateModified": "2026-11-05T13:07:29+00:00",
    "datePublished": "2026-11-05T13:07:29+00:00",
    "headline": "Show HN: Firenook – Firebase emulators in Rust: 40× faster writes, 10× less RAM",
    "image": {
      "@type": "ImageObject",
      "caption": "Firenook: A faster drop-in replacement for the Firebase Local Emulator Suite",
      "height": 90,
      "url": "https://firenook.dev/og/home.png",
      "width": 160
    },
    "timeRequired": "PT9M",
    "url": "https://firenook.dev/",
    "wordCount": 1912
  },
  "name": "Archived snapshot: Show HN: Firenook – Firebase emulators in Rust: 40× faster writes, 10× less RAM",
  "preview": {
    "alt": "Firenook: A faster drop-in replacement for the Firebase Local Emulator Suite",
    "color": null,
    "height": 90,
    "placeholder": {
      "data_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
      "hash": ""
    },
    "url": "https://firenook.dev/og/home.png",
    "width": 160
  },
  "reading_minutes": 9,
  "replicated_at": null,
  "source": "hnrss-org",
  "source_name": "Hacker News: Front Page",
  "summary": "Hi HN, we have been developing with Firebase for a long time, and the only way Firebase developers can build apps without directly costing them is using the official Firebase Emulator Suite. However, the issue with this suite is, it's dependent and running on Java with a old Console UI (not updated in years), that was not built to support tons and millions of data and has pretty bad developer experience. For a long time, we were hitting Out of Memory on even high specs laptop while developing and the worst part is while this happens all the persists data keep getting lost. We were honestly frustrated with this, and thought what if we built the Firebase Emulator Suite the right way, as it always should have been. Introducing Firenook, a faster drop-in replacement for Firebase Emulator Suite for Firebase developers. It's 40x faster writes and needs 10x less RAM to run it. We took the right approach of first building it Rust as a single engine, so that there will be no Java dependencies and built from scratch a new Console UI using modern web stacks. The result is, now we were able to run 2 millions datas loaded to Firenook with only taking around 2GB ram compared to 22GB of the official suite. Things are way faster and rebuilt Console UI gives best developer experience from logging Firebase Functions, to editing Firestore documents in JSON and many more. We developed this throughly for around 2 months now and ran this internally for a month before we decided it's time to release it to public so that other devs can make use of Firenook and also contribute it to make it better. Firenook is still new and I'm sure it misses things. So please try it our on your project and let us if there are any issues. Thank you. Comments URL: https://news.ycombinator.com/item?id=50378643 Points: 123 # Comments: 17",
  "tags": [],
  "temporalCoverage": "2026-11-06T11:27:16.888185679+00:00",
  "title": "Show HN: Firenook – Firebase emulators in Rust: 40× faster writes, 10× less RAM",
  "url": "https://aggr.aymericbeaumet.com/items/hnrss-org/2026-11-05-show-hn-firenook-firebase-emulators-in-rust-40x-faster/",
  "word_count": 1912
}