The Frustration That Started It All
Picture this: You're deep in a debugging session. Your terminal is split between your code editor, logs streaming in real-time, and a test runner. You're in the zone. Then you need to check a document in Firestore.
Alt-tab. Open browser. Navigate to Firebase Console. Wait for it to load. Click on your project. Wait again. Click Firestore. Expand the collection. Scroll. Find the document. Click it. Finally see the data.
By the time you get back to your terminal, you've lost your train of thought. The context switch killed your flow.
If you've worked with Firebase Firestore, you know exactly what I'm talking about. The Firebase Console is fine for occasional use, but when you're actively developing and need to check data constantly, it becomes a bottleneck.
I kept thinking: Why can't I just browse Firestore from my terminal?
So I built it.
Introducing LazyFire
LazyFire is a terminal user interface (TUI) for browsing Firebase Firestore. It's heavily inspired by lazygit - the fantastic terminal UI for git that changed how many of us interact with version control.
The core philosophy is simple: stay in your terminal, stay in your flow.
LazyFire connects to your Firestore database using your existing Firebase CLI credentials. No separate authentication, no API keys to manage - if you can run firebase commands, you can run LazyFire.
The Interface
When you launch LazyFire, you're greeted with a clean, multi-panel interface:
┌─ Projects ────┬─ Collections ─┬─ Tree ─────────────┬─ Details ──────────────┐
│ │ │ │ │
│ 🔥 my-app │ 📁 users │ ▼ 📁 users │ { │
│ my-app-stg │ 📁 products │ 📄 user_001 │ "name": "John Doe", │
│ my-app-dev │ 📁 orders │ 📄 user_002 │ "email": "john@...", │
│ │ 📁 analytics │ ▶ 📁 products │ "created": "2024..." │
│ │ │ │ } │
├───────────────┴───────────────┴────────────────────┴────────────────────────┤
│ Commands: GET users/user_001 ✓ 234ms │
└─────────────────────────────────────────────────────────────────────────────┘
Five panels, each with a purpose:
- Projects - All your Firebase projects, pulled from your CLI config
- Collections - Root-level collections in the selected project
- Tree - Documents and subcollections in an expandable tree view
- Details - The selected document's data with syntax highlighting
- Commands - A log of API calls with timing information
You can navigate between panels with h and l (or arrow keys), and move within lists using j and k. If you've used vim or lazygit, you'll feel right at home.
Feature Deep Dive
Let me walk you through the features that make LazyFire genuinely useful for day-to-day development.
Vim-Style Navigation
Everything is keyboard-driven. Here's the complete keybinding reference:
| Key | Action |
|---|---|
h ←
|
Move to left panel |
l →
|
Move to right panel |
j ↓
|
Move down in list |
k ↑
|
Move up in list |
Tab |
Jump to details panel |
Enter |
Select item / Expand collection |
Space |
Toggle expand/collapse |
v |
Enter visual select mode |
F |
Open query builder |
/ |
Filter current panel |
c |
Copy JSON to clipboard |
s |
Save JSON to file |
e |
Open in external editor |
r |
Refresh current view |
? |
Show help |
@ |
Show command history |
Esc |
Go back / Cancel |
q |
Quit |
The beauty of these keybindings is muscle memory. After a few sessions, you'll be flying through your database without thinking about it.
Expandable Tree View with Subcollections
Firestore's nested structure is fully supported. When you select a collection, LazyFire loads its documents. Each document can be expanded to reveal its subcollections, which can themselves be expanded to show their documents, and so on.
▼ 📁 users
📄 user_001
▼ 📁 orders
📄 order_abc
📄 order_def
▶ 📁 items
▶ 📁 preferences
📄 user_002
▶ 📁 products
The arrow indicators (▶ for collapsed, ▼ for expanded) make it easy to see the current state at a glance. Collection folders are cyan, document icons are green - subtle color coding that helps you parse the tree quickly.
Interactive Query Builder
This is one of my favorite features. Press F (Shift+F) on any collection or subcollection to open the query builder:
How it works:
- Navigate with
j/kbetween rows (WHERE, ORDER BY, LIMIT, buttons) - Navigate with
h/lbetween fields within a row - Press
Enterto edit a field - Press
ato add a new filter condition - Press
dto delete a filter - Tab through operators and value types using popup selectors
Supported operators:
- Comparison:
==,!=,<,<=,>,>= - Array operations:
in,not-in,array-contains,array-contains-any
Value types:
-
auto- LazyFire guesses the type (string, number, boolean) -
string- Force string interpretation -
integer- Force integer -
double- Force floating point -
boolean- Force boolean -
null- Null value -
array- Comma-separated values forin/not-inoperators
When you execute the query, results replace the tree view (or appear under the subcollection if you queried a nested collection). It's a massive time saver compared to writing queries in code or using the Firebase Console.
jq Query Support
The details panel shows your document as syntax-highlighted JSON. But what if you only care about a specific field? Or you want to transform the data before copying it?
Press / in the details panel and enter a jq expression:
| Filter | What it does |
|---|---|
.name |
Extract just the name field |
.address.city |
Nested field access |
.users[0] |
First element of users array |
.users[].name |
All names from users array |
| `.data \ | keys` |
| `.items \ | length` |
select(.status == "active") |
Filter by condition |
The filtered result is displayed in the details panel. Here's the powerful part: when a jq filter is active, copy and save operations use the filtered result, not the full document.
This means you can:
- Open a complex document
- Filter to just the fields you need with
.data.users[].email - Press
cto copy only those email addresses to your clipboard
No more copying a massive JSON blob and manually extracting what you need.
Visual Select Mode
Sometimes you need to fetch multiple documents at once. Visual select mode makes this painless.
- Press
vin the tree panel to enter select mode - Move up/down with
j/kto extend your selection (works in both directions, like vim) - Selected documents are highlighted with a dim yellow
+marker - Press
Spaceto fetch all selected documents in parallel - Press
Enterto view the combined results - Press
Escto exit select mode
The parallel fetching is key here. Instead of fetching documents one by one (which would be slow due to network latency), LazyFire fires off all requests simultaneously. Even fetching 20 documents feels instant.
Smart Caching
Network calls are expensive. LazyFire implements a two-level caching system:
Document cache - Once you fetch a document's data, it's cached. You'll see a small yellow dot
·next to cached documents in the tree.Collection cache - When you expand a collection, the list of documents is cached. Collapsing and re-expanding uses the cache instead of hitting the API again.
This makes navigation feel snappy. The first time you expand a collection, there's a brief loading spinner. After that, it's instant.
The cache is session-based (cleared when you quit) and can be refreshed anytime with r.
Syntax Highlighting
Document JSON is displayed with full syntax highlighting using the chroma library:
- Keys are colored distinctly from values
- Strings, numbers, booleans, and nulls each have their own color
- Proper indentation for nested objects
- Large documents are scrollable
It's a small thing, but it makes a huge difference when you're scanning through document data.
External Editor Integration
Press e in the details panel to open the current document in your external editor. LazyFire checks these environment variables in order:
$EDITOR$VISUAL- Falls back to
nvimif installed, otherwisevim
The document opens as a temporary JSON file. This is read-only for now (edits aren't saved back to Firestore), but it's useful when you need vim's full power to search or analyze a complex document.
Customizable Themes
LazyFire comes with a clean default theme, but you can customize every color. Create a config file at ~/.lazyfire/config.yaml:
ui:
# Nerd Fonts version: "3", "2", or "" to disable icons
nerdFontsVersion: "3"
theme:
activeBorderColor:
- "#ed8796"
- bold
inactiveBorderColor:
- "#5f626b"
optionsTextColor:
- "#8aadf4"
selectedLineBgColor:
- "#494d64"
Color options:
-
Named colors:
black,red,green,yellow,blue,magenta,cyan,white,default -
Hex colors:
#ed8796,#ff79c6, etc. -
256-color palette: Numbers
0through255 -
Attributes:
bold,underline,reverse
Example themes:
Catppuccin Macchiato:
ui:
theme:
activeBorderColor: ["#ed8796", "bold"]
inactiveBorderColor: ["#5f626b"]
optionsTextColor: ["#8aadf4"]
selectedLineBgColor: ["#494d64"]
Dracula:
ui:
theme:
activeBorderColor: ["#ff79c6", "bold"]
inactiveBorderColor: ["#6272a4"]
optionsTextColor: ["#8be9fd"]
selectedLineBgColor: ["#44475a"]
Tokyo Night:
ui:
theme:
activeBorderColor: ["#7aa2f7", "bold"]
inactiveBorderColor: ["#565f89"]
optionsTextColor: ["#7dcfff"]
selectedLineBgColor: ["#292e42"]
Mouse Support
While keyboard navigation is the primary interface, LazyFire also supports mouse input:
- Click on any panel to focus it
- Click on items to select them
- Click outside a popup to close it
This makes it accessible to team members who might not be familiar with vim-style navigation.
Nerd Font Icons
If you use a Nerd Font (and you should - they're great), LazyFire displays beautiful icons throughout the interface:
- 🔥 Firebase flame for the welcome screen and projects
- 📁 Folder icons for collections
- 📄 Document icons for documents
- Various status indicators
If icons don't display correctly, you can switch to Nerd Fonts v2 compatibility mode or disable icons entirely:
ui:
nerdFontsVersion: "2" # For older Nerd Fonts
# or
nerdFontsVersion: "" # Disable icons
Installation
Getting started takes less than a minute.
Homebrew (macOS/Linux)
brew tap marjoballabani/tap
brew install lazyfire
Go Install
If you have Go installed:
go install github.com/marjoballabani/lazyfire@latest
From Source
git clone https://github.com/marjoballabani/lazyfire.git
cd lazyfire
go build -o lazyfire .
./lazyfire
Download Binary
Pre-built binaries for macOS and Linux are available on the releases page.
Prerequisites
-
Firebase CLI - Install with
npm install -g firebase-tools -
Firebase Authentication - Run
firebase loginif you haven't already - Terminal with true color support - Most modern terminals (iTerm2, Alacritty, Kitty, Windows Terminal) support this
- Nerd Font (optional) - For icons. Download here
Quick Start
Once installed, getting started is simple:
# Make sure you're logged in
firebase login
# Launch LazyFire
lazyfire
You'll see a welcome screen with your Firebase projects. Use j/k to navigate, Enter to select a project, and start exploring.
Pro tip: If you work with multiple Firebase projects, LazyFire remembers them all. Switch between production, staging, and development environments without re-authenticating.
The Tech Behind It
For those curious about the implementation:
Language: Go - chosen for its excellent cross-platform support, single binary distribution, and strong concurrency primitives (goroutines make parallel document fetching trivial)
Terminal UI: gocui - Jesse Duffield's fork of the gocui library, which powers lazygit. It's battle-tested and handles all the complexity of terminal rendering.
jq Implementation: gojq - A pure Go implementation of jq. No external dependencies, works on all platforms.
Syntax Highlighting: chroma - Fast, accurate syntax highlighting with theme support.
Firebase API: Direct REST API calls using the access token from Firebase CLI. No Firebase Admin SDK means fewer dependencies and a smaller binary.
The entire application is around 5,000 lines of Go code. It's not a massive project, but every feature is intentional and polished.
Why I Built This
I'll be honest: I built this for myself.
I spend most of my working day in the terminal. Neovim for editing code, lazygit for version control, various CLIs for deployment and infrastructure. My terminal is my IDE, and I've optimized it over years to minimize friction.
But Firestore was always the exception. Every time I needed to check a document or verify that a write succeeded, I had to leave my terminal and open a browser. It broke my concentration every single time.
One day, after the hundredth alt-tab to the Firebase Console, I thought: "lazygit exists for git... why doesn't something like this exist for Firestore?"
I couldn't find anything that fit the bill, so I built it.
The first version was rough - just enough to browse collections and view documents. But over time, I kept adding features that would save me time:
- "I keep running the same queries" → Query builder
- "I just want to see one field" → jq support
- "Fetching documents one by one is slow" → Visual select mode + parallel fetching
- "I hate waiting for data to load again" → Caching
Each feature came from real frustration during real development work. That's why LazyFire feels cohesive - it's not a collection of features someone thought might be useful, it's a collection of solutions to problems I actually had.
What's Next
LazyFire is actively maintained and I have a roadmap of features I'm considering:
Near-term:
- Document editing (create, update, delete) - currently read-only
- Batch operations on selected documents
- Export to CSV format
Medium-term:
- Firestore emulator support for local development
- Realtime listeners for live document updates
- Saved queries that persist across sessions
Long-term:
- Firebase Auth user browsing
- Cloud Functions log viewing
- Multiple database support (for projects with multiple Firestore instances)
If any of these would be particularly useful for your workflow, let me know in the comments or open an issue on GitHub. User feedback directly influences what I prioritize.
Try It Out
The project is open source under the MIT license:
github.com/marjoballabani/lazyfire
If you work with Firestore and spend any amount of time in the terminal, give it a try. The installation takes 30 seconds, and you might find it changes how you interact with your database.
Stars on GitHub are always appreciated - they help others discover the project. And if you run into any issues or have feature requests, please open an issue. I read every single one.
About Me
I'm Marjo Ballabani, a software developer who believes that good developer tools should get out of your way. I build things that make my workflow faster, and sometimes those things are useful to others too.
You can find me on GitHub where I occasionally open source projects like this one.
What terminal tools have changed your workflow? I'd love to hear about your favorite TUIs and CLI tools in the comments below!


Top comments (0)