I was working on a React project when I ran into a performance problem.
The application worked.
The Lighthouse score wasn't terrible.
But something still felt wrong.
Some interactions felt sluggish. Components were rendering more than I expected. And whenever I found a performance problem, I had the same question:
Why is this happening?
Lighthouse is great at telling us about the performance of a web page — Core Web Vitals, network requests, resource sizes, loading performance, and more.
But when you're debugging a React application, sometimes you need to go deeper.
You need to know what is happening inside React.
That's what led me to build React Doctor.
The Idea
I wanted a tool that could combine two different perspectives:
What does the code look like?
and
What actually happens when the application runs?
So I built React Doctor as a CLI-based React performance analysis tool that combines static code analysis with runtime profiling.
The goal isn't to replace Lighthouse.
It's to answer a different question:
What in my React application is contributing to the performance problem?
How React Doctor Works
The analysis pipeline combines several stages:
React project
↓
File Scanner
↓
Static Analyzer
↓
Runtime Profiler
↓
Rule Engine
↓
Report Compiler
↓
Dashboard
1. Static Analysis
React Doctor analyzes JSX/TSX code using AST-based analysis.
It can identify patterns such as:
- unnecessary console logs
- potentially expensive component structures
- inline functions and other patterns that can contribute to unnecessary work
- oversized components
- other React-related code smells
This happens without needing to wait for the application to run.
2. Runtime Profiling
Static analysis isn't enough.
A pattern in the source code doesn't automatically mean that it causes a real performance problem.
So React Doctor also launches the application in a real browser environment and collects runtime information.
It can capture metrics such as:
- LCP
- FCP
- CLS
- INP
- TTFB
- render/commit timing
- component re-render information
- screenshots at important moments
The profiler can also test under different device and network conditions to make performance problems easier to reproduce.
3. Combining the Two
This is the part I found most interesting.
A static warning by itself doesn't always mean much.
A runtime problem by itself doesn't always tell you where to look.
But combining them can provide much more useful context.
For example:
Static analysis:
A component contains a potentially expensive render pattern.
Runtime:
The component is rendering repeatedly during interaction.
Result:
This pattern may be contributing to unnecessary work.
Instead of simply saying:
"Your application is slow."
the goal is to help answer:
"What is happening, where is it happening, and what should I investigate?"
The CLI
React Doctor is available on npm under:
react-doctor-cli-dev
You can run it with npx:
npx react-doctor-cli-dev full ./my-app
Or install it globally:
npm install -g react-doctor-cli-dev
react-doctor full ./my-app
The CLI currently provides commands for different types of analysis:
react-doctor full ./my-app
react-doctor analyze ./my-app
react-doctor profile ./my-app
react-doctor dashboard
The full command runs the complete analysis pipeline.
What the Report Looks Like
The output is designed to be more useful than a list of warnings.
For each detected issue, the report can provide information such as:
- the affected file
- the relevant component
- what was detected
- why it may matter
- supporting runtime information
- suggestions for investigation or improvement
The project also generates structured report data that can be consumed by the dashboard.
Why Not Just Use Lighthouse?
Because I don't think this is an either/or situation.
Lighthouse is extremely useful.
It tells you a lot about how your page performs from the browser and web-platform perspective.
React Doctor is focused on a different layer:
Web Performance
│
┌──────────────┴──────────────┐
│ │
Browser/Web React/Application
perspective perspective
│ │
Lighthouse React Doctor
Lighthouse can tell you that your LCP is slow.
React Doctor is intended to help you investigate what is happening in the React application that may be contributing to that experience.
They're complementary tools, not competitors.
Building It as a Graduation Project
React Doctor started from a real performance problem I encountered while working on another project.
I began developing the idea around October 2025, and eventually turned it into my final-year Software Engineering graduation project.
I built it with my teammate as a full project rather than just a proof of concept.
The stack ended up including:
- TypeScript
- Node.js
- Babel AST
- Puppeteer
- web-vitals
- Express
- SQLite
- React
The project is structured as a monorepo and contains the CLI, analysis pipeline, profiling system, backend, and dashboard.
And Then I Published It
After finishing the project, I decided not to leave it sitting in a university repository.
I published the CLI to npm under the name:
react-doctor-cli-dev
Since publishing it, the package has passed 3,600+ npm downloads in about two months.
For a project that started as a performance problem I encountered while building something else, seeing people actually install it has been one of the most rewarding parts of the project.
It has also given me a lot of feedback about what developers actually want from a tool like this.
What I Learned
1. Performance Problems Aren't Always Obvious
A page can have a respectable Lighthouse score and still feel bad during interaction.
Performance isn't just one number.
2. Static Analysis and Runtime Analysis Complement Each Other
Static analysis can tell you:
"This pattern exists."
Runtime profiling can tell you:
"This is what actually happened."
Neither tells the complete story by itself.
3. Developer Tools Need Context
A warning isn't very useful if the developer doesn't know what to do with it.
One of the things I focused on was making the results understandable instead of simply dumping raw metrics and AST findings.
4. Building Something People Can Actually Install Is Different
Publishing the project to npm changed the way I think about software projects.
A graduation project can end when you submit it.
An open-source tool doesn't.
Once other developers start installing it, you suddenly have to think about:
- installation
- documentation
- compatibility
- error handling
- package size
- CLI UX
- releases
- feedback
- actual developer workflows
That has probably been one of the most valuable parts of the experience.
What's Next?
There are several things I want to explore next:
- GitHub Actions / CI integration
- performance budgets
- regression detection
- better reporting
- custom rules
- improved runtime analysis
- better developer workflows around performance debugging
The project is still evolving, and I'm especially interested in hearing from developers who have dealt with difficult React performance problems.
I'd Love Your Feedback
If you work with React:
What performance problems do you usually struggle to diagnose?
Is it:
- unnecessary re-renders?
- slow interactions?
- large components?
- state management?
- expensive computations?
- bundle size?
- something else?
And more importantly:
What would you want a React performance tool to tell you that your current tools don't?
I'd genuinely like to hear about real problems you've encountered.
Try React Doctor
🐙 GitHub:
https://github.com/softar-dev/React_Doctor
📦 npm:
https://www.npmjs.com/package/react-doctor-cli-dev
🌐 Documentation:
https://react-doctor-cli.web.app
👨💻 My Portfolio:
https://oussamah-kabalan.netlify.app
If you try it, I'd love to hear what you find — especially if the analysis catches something you weren't expecting.
React Doctor is an open-source React performance analysis project built as my Software Engineering graduation project.
Top comments (0)