Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/check-version.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Version check

on:
pull_request:
branches: [main]
paths:
- "packages/react-doctor/package.json"
workflow_call:

jobs:
check-version:
runs-on: ubuntu-latest
permissions:
packages: read
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: "https://npm.pkg.github.com"
scope: "@proda-ai"

- name: Verify version is not already published
working-directory: packages/react-doctor
run: |
VERSION=$(node -p "require('./package.json').version")
echo "Checking @proda-ai/react-doctor@$VERSION..."
if npm view "@proda-ai/react-doctor@$VERSION" version --registry=https://npm.pkg.github.com 2>/dev/null; then
echo ""
echo "❌ Version $VERSION is already published to GitHub Packages."
echo " Bump the version in packages/react-doctor/package.json before merging."
exit 1
fi
echo "✅ Version $VERSION is available for publishing"
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 changes: 40 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Publish to GitHub Packages

on:
push:
branches: [main]
paths:
- "packages/react-doctor/**"

jobs:
version-check:
uses: ./.github/workflows/check-version.yml

publish:
needs: version-check
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: "https://npm.pkg.github.com"
scope: "@proda-ai"
cache: pnpm

- run: pnpm install --frozen-lockfile

- name: Build
working-directory: packages/react-doctor
run: pnpm build

- name: Publish
working-directory: packages/react-doctor
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
78 changes: 76 additions & 2 deletions packages/react-doctor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,82 @@
<img alt="React Doctor" src="./assets/react-doctor-readme-logo-light.svg" width="180" height="40">
</picture>

[![version](https://img.shields.io/npm/v/react-doctor?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/react-doctor)
[![downloads](https://img.shields.io/npm/dt/react-doctor.svg?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/react-doctor)
# `@proda-ai/react-doctor`

> **This is a Proda fork of [millionco/react-doctor](https://github.com/millionco/react-doctor).**

## Why this fork exists

React Doctor has hardcoded thresholds (e.g. 300 lines for `no-giant-component`) with no way to configure them per-directory or per-rule. The upstream config only supports globally ignoring rules or files — there is no middle ground.

We needed:

- **Per-directory threshold overrides** — view components are naturally larger than leaf components, and a single global limit doesn't fit both
- **Bug fixes** not yet released upstream (e.g. [#113](https://github.com/millionco/react-doctor/issues/113) — non-existent `jsx-a11y/no-noninteractive-element-interactions` rule breaking the score)

This fork is published as `@proda-ai/react-doctor` on GitHub Packages. Upstream contributions are welcome and will be submitted back when possible.

## What's different from upstream

| Change | Status |
| ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| Remove non-existent `jsx-a11y/no-noninteractive-element-interactions` rule ([#113](https://github.com/millionco/react-doctor/issues/113)) | ✅ Merged |
| Configurable per-directory thresholds via `react-doctor.config.json` | 🔜 On branch `feat/configurable-thresholds` |

### Configurable thresholds (planned)

```json
{
"thresholds": {
"component-lines": {
"default": 300,
"overrides": [{ "files": ["src/ui/views/**"], "max": 400 }]
}
}
}
```

## Versioning

Versions follow `{upstream}-proda.{N}`:

| Version | Meaning |
| ---------------- | -------------------------------------------------- |
| `0.0.30-proda.1` | Based on upstream `0.0.30`, Proda patch 1 |
| `0.0.30-proda.2` | Same upstream base, next Proda change |
| `0.0.31-proda.1` | After merging upstream `0.0.31`, first Proda patch |

The version is **set manually** in `packages/react-doctor/package.json` as part of the PR. Bump the `proda.N` suffix when making changes.

## CI / CD

### On pull requests

- **CI / test** — runs tests, lint, and format checks (upstream workflow)
- **Version check** — if `package.json` was changed, verifies the version doesn't already exist in GitHub Packages. Fails with a clear message if you forgot to bump

### On merge to main

- **Publish** — builds with Node 24, verifies the version is new (safety net), and publishes `@proda-ai/react-doctor` to GitHub Packages. No manual steps needed

### How to release a new version

1. Make your changes in a PR
2. Bump the version in `packages/react-doctor/package.json` (increment the `proda.N` suffix)
3. CI validates the version is available
4. Merge — package is published automatically

### Syncing with upstream

1. `git fetch upstream && git merge upstream/main`
2. Update the base version to match upstream (e.g. `0.0.31-proda.1`)
3. Resolve conflicts if any, open a PR

---

_Original README follows below._

---

Let coding agents diagnose and fix your React code.

Expand Down
13 changes: 8 additions & 5 deletions packages/react-doctor/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-doctor",
"version": "0.0.30",
"name": "@proda-ai/react-doctor",
"version": "0.0.30-proda.1",
"description": "Diagnose and fix performance issues in your React app",
"keywords": [
"diagnostics",
Expand All @@ -9,15 +9,15 @@
"performance",
"react"
],
"homepage": "https://github.com/aidenybai/react-doctor#readme",
"homepage": "https://github.com/proda-ai/react-doctor#readme",
"bugs": {
"url": "https://github.com/aidenybai/react-doctor/issues"
"url": "https://github.com/proda-ai/react-doctor/issues"
},
"license": "MIT",
"author": "Aiden Bai",
"repository": {
"type": "git",
"url": "https://github.com/aidenybai/react-doctor.git",
"url": "https://github.com/proda-ai/react-doctor.git",
"directory": "packages/react-doctor"
},
"bin": {
Expand All @@ -41,6 +41,9 @@
"default": "./dist/react-doctor-plugin.js"
}
},
"publishConfig": {
"registry": "https://npm.pkg.github.com"
},
"scripts": {
"dev": "tsdown --watch",
"build": "rm -rf dist && NODE_ENV=production tsdown",
Expand Down
1 change: 0 additions & 1 deletion packages/react-doctor/src/oxlint-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ export const createOxlintConfig = ({
"jsx-a11y/anchor-is-valid": "warn",
"jsx-a11y/click-events-have-key-events": "warn",
"jsx-a11y/no-static-element-interactions": "warn",
"jsx-a11y/no-noninteractive-element-interactions": "warn",
"jsx-a11y/role-has-required-aria-props": "error",
"jsx-a11y/no-autofocus": "warn",
"jsx-a11y/heading-has-content": "warn",
Expand Down
Loading