npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-luau-doctor

v0.1.0

Published

Local React Lua and ReactRoblox diagnostics with coding-agent handoff

Readme

React Luau Doctor

Local, deterministic diagnostics for React Lua and ReactRoblox projects, with a first-class repair workflow for coding agents. The analyzer reports likely root causes and remediation steps; it never applies source patches itself.

Release identity: Written clearance for the development identity was not recorded, so this release is published as React Luau Doctor / react-luau-doctor. It is not affiliated with or endorsed by Meta or the React team. See Meta's React trademark policy.

This Luau port is derived from millionco/react-doctor and preserves its diagnostic-report and coding-agent workflow for React Lua projects. The Rust analyzer, Luau semantic rules, and Luau fixtures are independently authored. The adapted CLI is pinned to React Doctor's last plain-MIT snapshot; see LICENSE, THIRD_PARTY_NOTICES.md, and the exact source record in PROVENANCE.md.

Install

The npm package requires Node.js 20 or newer and installs one platform-specific optional dependency:

npm install --save-dev react-luau-doctor
npx react-luau-doctor .

On a fallback-branded release, use react-luau-doctor in both commands. Native archives are also published for Windows, macOS, and glibc Linux on x64 and ARM64. The npm launcher only selects an already-installed executable—it never downloads a binary or runs an installer. In a source checkout it also recognizes target/release and target/debug, which makes this development flow work:

cargo build --release
node bin/react-doctor-luau.js .

Scan a project

# Full local scan; findings are advisory by default
react-luau-doctor .

# Show every rule and diagnostic location
react-luau-doctor . --verbose

# Only findings introduced relative to main, blocking on warnings
react-luau-doctor . --scope changed --base main --blocking warning

# Compare the staged index with HEAD
react-luau-doctor . --staged --scope changed

# Machine-readable report without a score
react-luau-doctor . --json-out report.json --no-score

The scan command accepts --scope full|files|changed|lines, --base <ref>, --staged, repeatable --project <path>, --blocking none|warning|error, --config, --score, --json, --json-out, --no-score, --no-warnings, and --no-agent-prompt. Human output also accepts --verbose, --color auto|always|never, --no-color, and --ascii. The default report mirrors React Doctor's concise flow: it groups repeated findings, shows representative sites for the top three error rules, summarizes every category, and finishes with the doctor score card. Run react-luau-doctor --help for the complete interface.

Interactive terminals receive the colorful report automatically. Redirected output, CI, NO_COLOR, and TERM=dumb use an unstyled fallback; --color always and --color never provide explicit control. JSON output never contains terminal styling.

Additional commands are available for setup and reference:

react-luau-doctor init
react-luau-doctor rules list
react-luau-doctor rules explain react-luau/rules-of-hooks
react-luau-doctor why src/interface/Views/Hotbar.luau:203

why <file>:<line>[:column] rescans the project and opens a focused, syntax-colored explanation at that location: the triggering code, rule intent, confidence, remediation, and a Luau before/after pattern.

Exit code 0 means the configured threshold was not reached, 1 means it was, and 2 means analysis was incomplete or failed. A missing comparison base, malformed configuration, or parser/analyzer failure is never presented as a clean result.

Scope semantics

| Scope | Included diagnostics | | --- | --- | | full | Every finding in selected projects | | files | Every finding in files changed from the base | | changed | Findings introduced relative to the base | | lines | Findings intersecting added or modified lines |

--staged reads index content and compares it with HEAD; it does not check out or rewrite files. Baseline fingerprints tolerate line movement and renames while distinguishing duplicate occurrences.

Repair with a coding agent

Coding-agent repair is a supported workflow, not an incidental use of JSON:

# Detect and launch Codex, Claude Code, or Cursor Agent
react-luau-doctor agent . --target auto

# Prepare a bundle and print its prompt without launching anything
react-luau-doctor agent . --target stdout --max-groups 3

# Install project-local guidance for selected agents
react-luau-doctor install --agents codex,claude,cursor --yes

# Hooks are always a separate, explicit choice
react-luau-doctor install --agents codex,claude --agent-hooks --yes
react-luau-doctor uninstall --agent-hooks

Each handoff contains prompt.md, diagnostics.json, manifest.json, and a short document for every included rule. Like React Doctor, the prompt selects three priority rule groups and shows at most three representative locations per group. fixGroupId remains in the full report so the agent can repair shared root causes within each rule group. If agent launch or clipboard access fails, the full prompt and bundle path are printed.

The handoff asks the agent to inspect and confirm each finding, preserve behavior, make narrowly scoped changes, run the exact diagnostic command before and after editing, and separate resolved, unresolved, and human-review work. Launches use the agent's normal terminal, sandbox, and approvals. This project never passes permission-bypass options such as --yolo, --dangerously-skip-permissions, or equivalents.

With explicit hook consent, supported agents rerun a changed-scope warning scan after edit operations. Hooks have a 30-second timeout and fail open. Unsupported agents rely on the installed skill's mandatory final verification step.

Configuration and suppressions

The default project configuration is react-luau.toml. CLI flags override it.

include = ["src/**/*.luau", "src/**/*.lua"]
exclude = ["src/generated/**"]
react_modules = ["Packages.React"]
additional_hooks = ["useStore"]
effect_hooks = ["useTrackedEffect"]
blocking = "warning"
warnings = true

[rules]
"react-luau/exhaustive-deps" = "warning"
"react-luau/binding-getvalue-in-render" = "off"

Narrow source suppressions are available when a diagnostic is intentionally not actionable:

-- react-luau-disable-next-line react-luau/exhaustive-deps
React.useEffect(function() doWork(value) end, {})

-- react-luau-disable react-luau/opaque-children
-- ...small intentional region...
-- react-luau-enable react-luau/opaque-children

Default rules

Rules are conservative and Luau-aware. A rule is enabled by default only after meeting the project's precision gate on independently written fixtures.

| Rule | Default | Detects | | --- | --- | --- | | react-luau/rules-of-hooks | error | Hooks in invalid control-flow or function contexts | | react-luau/exhaustive-deps | warning | Proven captured reactive values missing from dependencies | | react-luau/inline-dependencies | warning | Non-inline dependency tables | | react-luau/set-state-in-render | error | Unconditional state updates during render | | react-luau/immutable-props-state | error | Direct mutation of props or state | | react-luau/binding-getvalue-in-render | warning | Proven binding :getValue() calls during render | | react-luau/opaque-children | warning | Indexing, iterating, measuring, or mutating opaque children | | react-luau/react-none-as-prop | warning | React.None used as an element prop | | react-luau/multiple-key-sources | warning | Both a table key and an explicit key prop | | react-luau/missing-list-key | warning | Array/numeric children without a stable key | | react-luau/effect-connection-cleanup | warning | Proven effect-owned connections without cleanup | | react-luau/unsupported-reactroblox-api | error | Calls to APIs omitted by ReactRoblox |

Rules follow the maintained React Lua repository's React API, Luau deviations, and ReactRoblox API.

Reports and score

JSON schema v1 includes scan mode and completeness, React detection, analyzed files/lines, structured failures, diagnostics and remediation metadata, summary, baseline delta, and score metadata. Reports are path-and-span sorted so identical inputs produce stable output even though files are analyzed concurrently.

The optional score comes from React Doctor's upstream score service; this port does not invent or reproduce a local scoring formula. For each detected React project, the CLI sends a gzip-compressed POST to https://www.react.doctor/api/score. The payload is a sanitized finding inventory containing only rule IDs, severities, static rule metadata, and fixed protocol placeholders. It never contains source text, file paths, repository or commit identity, fingerprints, enclosing symbols, or diagnostic-specific symbol names.

The service owns the numeric score and label. Its weights and labels can change, so the same finding inventory may receive a different result after an upstream scoring update. The request times out after 10 seconds and fails open: diagnostics and blocking behavior remain available, while the report marks only the score as unavailable. --no-score disables every score and projection request and sends nothing to the service.

For changed and lines scopes, scoring uses the project's finding inventory before the scope's display filtering is applied. This keeps the project health score separate from the smaller set of findings shown for the current change. A multi-project report uses the lowest available project score. The concise human report may make one optional second sanitized request with the displayed top three error rules removed; that server-returned projection powers the ghost-gain segment in the score bar. If the projection request fails, the primary score and scan results remain unchanged.

Incomplete analysis, a non-React project, an explicit --no-score, and an unreachable score service are reported as distinct score states. None is presented as a locally calculated substitute.

GitHub Action

Released Action tags contain all six native binaries. The Action does not fetch an executable at runtime. Replace OWNER and the version below with the actual repository and release:

- uses: actions/checkout@v4
  with:
    fetch-depth: 0

- uses: OWNER/[email protected]
  id: doctor
  with:
    directory: .
    projects: |
      client
      shared
    scope: changed
    base: ${{ github.event.pull_request.base.sha }}
    blocking: warning
    comments: true
    annotations: true

- run: echo "Score ${{ steps.doctor.outputs.score }}"

The Action writes a job summary, emits up to 50 workflow annotations, and updates one marker-owned bot comment on pull requests when its token can write comments. Comment failure (common on untrusted fork PRs) is reported as a warning and does not hide the scanner result. Outputs include score, completeness, new/fixed/error/ warning counts, and a JSON array of affected files.

Privacy and safety

  • Scanning, fingerprinting, baseline comparison, and prompt generation run locally.
  • When scoring is enabled, the only network payload is the sanitized finding inventory described above. Source, paths, repository and commit identity, fingerprints, and symbols are never included.
  • --no-score sends no score or projection request.
  • PR summaries contain diagnostic metadata, not source text.
  • The analyzer suggests remediations but never writes patches.
  • Source providers read the working tree, Git objects, or staged index without checking out a baseline.
  • Dependency, generated, .git, Packages, DevPackages, node_modules, and vendor directories are excluded by default.

Parser compatibility

Version 0.1 pins full_moon 0.19 so the native crate remains buildable with the declared Rust 1.71 toolchain. It supports typed Luau, generics, type packs, compound assignments, interpolation, continue, if-expressions, and type assertions. Luau syntax introduced after that parser release (for example @native, user-defined type functions, leading union markers, or //=) is reported as a structured parse failure: the report is marked incomplete and the CLI exits 2. It is never treated as a clean scan. The parser is isolated behind ParserBackend so a later release can raise this grammar ceiling without coupling rules or source providers to one parser version.

Develop

cargo fmt --all -- --check
cargo test --all-targets --locked
npm test
cargo run -- . --scope full
# With cargo-fuzz installed on a supported nightly toolchain:
cargo fuzz run parse-and-analyze

Release tags build Windows x64/ARM64, macOS x64/ARM64, and glibc Linux x64/ARM64. Set the repository variable REACT_DOCTOR_LUAU_BRAND_CLEARED=true only after written clearance is recorded; when it is absent or false, release packages and commands are automatically rewritten to the fallback identity.

License

This project is MIT licensed. CLI presentation and workflow are adapted from React Doctor commit 0c198589d81702cc0b59cfe6d41e63329154e203, the last plain-MIT snapshot before upstream changed its license. The upstream copyright and license are retained in LICENSE and LICENSES/react-doctor-MIT.txt. Binary releases also retain THIRD_PARTY_NOTICES.md, including the MPL-2.0 notice for full_moon. Current Modified MIT React Doctor sources were inspected only to document the score-service protocol; no source code from those later revisions was copied into this project. See PROVENANCE.md for both records.