If you’ve ever opened a legacy project and felt your soul briefly leave your body, this one’s for you.
You know the scene:
- 200k+ lines of code
- Three architectural “eras” living in the same repo
- Tests that pass… somehow
- A PR review queue that feels like airport security
Let’s fix that.
This post is a practical, hands-on guide to using gemini-cli as a serious productivity multiplier — not as a gimmick, not as a toy, but as a real engineering tool you can plug into your daily workflow today. Btw, I’m not ‘with’ Google for many years now… so it’s all my personal thoughts.
By the end, you’ll know exactly how to:
- Explore massive codebases without losing your mind
- Refactor safely and confidently
- Pre-review your own PRs
- Generate useful tests (not garbage)
- Debug failures faster
- Automate repetitive dev work
Why Gemini-CLI?
Most AI tools live in your browser
gemini-cli lives inside your repo.
That means:
- It sees real files.
- It can modify them.
- It can run commands.
- It works in your terminal flow.
This is huge.
You’re not copy-pasting snippets back and forth. You’re operating on the actual codebase.
Think of it as:
grep + refactor engine + code reviewer + junior dev + documentation bot
all accessible from your terminal.
1. Exploring Large Codebases
You inherit a project.
You need to understand how authentication works.
Normally you:
- Open VS Code
- Search 14 times
- Open 11 tabs
- Forget what you were doing
Step 1: Locate Usage Patterns
gemini grep_search --pattern "authenticateUser" --include "*.js,*.ts"
You instantly get scoped results without manually filtering noise.
But don’t stop there.
Step 2: Build Context Before Asking for Refactors
AI works best with context.
gemini read_file --file_path "src/auth/authService.js"
gemini read_file --file_path "src/middleware/authMiddleware.js"
Now Gemini understands the flow. You can also tell it to scan all the JS files in a certain dir/repo.
Then ask:
gemini replace \
--file_path "src/auth/authService.js" \
--instruction "Refactor authenticateUser to async/await and improve error handling clarity."
Instead of blindly rewriting code, it rewrites within context.
2. Safe Refactoring Without Breaking Everything
Callback hell? Legacy promises? Weird side effects?
Before changing anything:
Step 1: Ask for a Refactor Plan
gemini ask "Explain how processAuthRequest works and list risks if converting to async/await."
This forces:
- Flow understanding
- Risk awareness
- Dependency mapping
Then refactor.
Step 2: Generate a Safer Rewrite
Instead of manually replacing text blocks, give an instruction:
gemini replace \
--file_path "src/auth/authService.js" \
--instruction "Convert processAuthRequest to async/await while preserving existing behavior and error propagation."
The key phrase is:
“preserving existing behavior.”
Always specify invariants and review/check what you get. Always.
3. Pre-Review Your Own PR (Game Changer)
Want fewer review comments?
Run this before pushing:
gemini ask "Review all modified files and list potential issues: edge cases, naming clarity, missing validation, security bugs and performance concerns."
Or go file-by-file:
gemini read_file --file_path "src/utils/dataProcessor.js"
gemini ask "Act as a senior reviewer and critique this file."
This catches:
- Missing null checks
- Inconsistent naming
- Poor error messages
- Forgotten logs
- Performance red flags
You instantly upgrade your PR quality.
Senior engineers do this mentally.
4. Generating Tests That Aren’t Trash
Let’s be honest.
Most AI-generated tests are:
expect(true).toBe(true);
Useless.
Instead, do this properly.
Step 1: Give the Implementation First
gemini read_file --file_path "src/services/analyticsService.js"
Step 2: Request Edge-Case Focus
gemini ask "Generate Jest tests for analyticsService with:
- success case
- failure case
- edge case (empty input)
- mock external dependencies"
Now you get meaningful coverage.
Step 3: Write the Test File
gemini write_file \
--file_path "test/services/analyticsService.test.js" \
--content "<generated test content>"
Then verify:
gemini run_shell_command --command "npx jest test/services/analyticsService.test.js"
Boom.
You just turned test writing from friction into flow.
5. Debugging Faster
Failing test:
TypeError: Cannot read property 'id' of undefined
at userController.js:75
Instead of guessing:
gemini read_file --file_path "src/controllers/userController.js"
gemini ask "Line 75 throws 'Cannot read property id of undefined'. Identify likely cause and suggest fix."
You’ll usually get:
- Root cause hypothesis
- Missing guard
- Validation improvement
- Suggested patch
That’s 15–30 minutes saved per bug.
Multiply that weekly.
6. Automating Repetitive Code Changes
Need to:
- Rename a function across the project?
- Replace deprecated API usage?
- Add logging to multiple modules?
You can batch operations.
Example:
gemini ask "Find all usages of deprecatedFunction and suggest replacement with newFunction including parameter mapping."
Then apply systematically.
This is safer than regex-only replaces because Gemini understands intent.
7. Using Gemini-CLI Strategically (Advanced Tips)
Here’s where developers level up.
A. Always Load Context First
Garbage context = garbage output.
Read dependent files before asking for big refactors.
B. Be Explicit About Constraints
Good prompt:
Refactor without changing public API. Maintain existing return types.
Bad prompt:
Make it better.
C. Use It for Thinking, Not Just Editing
Ask:
- “What edge cases are missing?”
- “What scaling issues will this cause?”
- “What happens if input is null?”
- “How would this fail in production?”
Now you’re using it as a reasoning amplifier.
D. Treat It Like a Junior Dev
It’s fast.
It’s capable.
But it still needs direction.
Review outputs.
Always.
Where Gemini-CLI Shines Most
✅ Large legacy migrations
✅ Codebase onboarding
✅ Boilerplate generation
✅ PR self-review
✅ Test scaffolding
✅ API documentation generation
✅ Debugging strange runtime errors
Where you should be careful:
⚠️ Security-critical code
⚠️ Concurrency-heavy systems
⚠️ Subtle performance optimizations
AI accelerates – You still own correctness.
Maybe, in the future with Gemini 5 or 6 it will be more ‘hands-off’ but these days it’s still not the case.
The Real Takeaway
This isn’t about replacing developers.
It’s about upgrading your throughput.
The best engineers in the next few years won’t be the ones typing fastest.
They’ll be the ones orchestrating intelligence fastest.
gemini-cli turns your terminal into a command center.
You stay focused on:
- Architecture
- Trade-offs
- System design
- Business impact
Let the machine handle:
- Boilerplate
- Refactors
- Mechanical fixes
- Repetition
That’s leverage.
If you’re building startups (and I know many of you are), speed without quality is chaos.
Speed with structured AI assistance?
That’s unfair advantage.
Discover more from Ido Green
Subscribe to get the latest posts sent to your email.