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

rails-doctor

v0.1.8

Published

Your agent writes bad Rails. This catches it. A static-analysis CLI for Ruby on Rails that scores your codebase 0-100 and installs as an agent skill for Claude Code, Codex, Cursor, and Copilot.

Downloads

214

Readme

rails-doctor

Your agent writes bad Rails. This catches it.

A static-analysis CLI for Ruby on Rails projects that scores your codebase 0–100, flags architecture and convention violations, and installs as an agent skill so Claude Code, Codex, Cursor, and Copilot write better Rails up front.

Codifies 37signals/DHH's Rails philosophy as enforceable rules. Framework-aware: Inertia/SPA stacks aren't penalized for skipping Hotwire, Sidekiq is allowed when configured, and deployment is intentionally not enforced.

Quick start

# Run a scan, no install needed
npx -y rails-doctor@latest scan .

# Install as an agent skill so Claude Code / Codex / Cursor write better Rails
npx -y rails-doctor@latest install

npx runs the bundled Ruby scanner via your system Ruby. No gem install required — every Rails developer already has Ruby on PATH.

Requirements: Node 18+ and Ruby 3.1+.

Use

npx -y rails-doctor@latest scan .                  # TTY output
npx -y rails-doctor@latest scan . --json           # machine-readable
npx -y rails-doctor@latest scan . --markdown       # GitHub PR-comment ready
npx -y rails-doctor@latest scan . --strict         # warnings become errors
npx -y rails-doctor@latest scan . --min-score 75   # exit non-zero below threshold
npx -y rails-doctor@latest scan . --with-external all   # also run brakeman/rubocop/etc.

npx -y rails-doctor@latest explain controllers/non-restful-action
npx -y rails-doctor@latest rules
npx -y rails-doctor@latest install --dry-run       # see which agents would get the skill

What it covers

First-party rules (no external dependencies)

| Category | Examples | |---|---| | Architecture | app/services/, app/policies/, app/queries/, hexagonal layouts, deeply-nested concern dirs | | Omakase Gemfile | banned gems (sidekiq, devise, draper, dry-rb, view_component, …) — all opt-out via allow:; recommended gems; dual-stack errors | | Models / concerns | concern size 5–150 LOC, trait-style naming, anemic-model detection (AST), fat-model detection, callback overuse, uniqueness-without-index, .pluck-over-.map | | Controllers (AST) | RESTful-only public actions, fat controllers, thin ApplicationController, before_action overuse | | Routes | member do / collection do, custom verbs (verbs-become-nouns) | | Migrations / DB | foreign-key indexes, foreign-key constraints, boolean state columns, mixed PK types | | Views / frontend | dual bundlers, SPA + importmap drift, missing resource partials, dom_id string literals, Stimulus naming and size, API/HTML controller drift | | Stack consistency | sprockets+propshaft, Solid Queue without Mission Control, vestigial importmap, redis+solid_cache, devise+has_secure_password, STI without type index | | Tests | spec/+test/ coexistence, factory_bot+fixtures coexistence, *_url over *_path |

Wrapped tools (opt-in, run automatically when in your Gemfile)

| Tool | Purpose | |---|---| | brakeman | Rails-specific security (SQLi, XSS, mass assignment, open redirect) | | bundler-audit | Vulnerable dependencies | | active_record_doctor | Schema findings (missing/unused indexes, orphaned FKs) | | rubocop | Style and lint | | reek | Code smells | | debride | Possibly unused methods | | traceroute | Unused or undefined route actions | | rubycritic | Aggregate quality grade per file |

Configuration

Drop a .rails-doctor.yml at your project root (full example: .rails-doctor.yml.example).

preset: default          # default | strict | omakase | minimal
allow:
  - sidekiq              # we use Sidekiq, don't suggest Solid Queue
  - inertia-react        # frontend uses Inertia (auto-detected too)
  - rspec
  - services             # we keep app/services for external API adapters
disable:
  - controllers/non-restful-action
severity:
  models/concern-too-large: error
thresholds:
  concern_max_loc: 150
  controller_max_loc: 200
  model_max_loc: 400
external:
  enabled: true
  tools: [brakeman, bundler-audit, active_record_doctor]

Scoring

Severity-weighted (error=5, warning=2, info=0.5), per-rule cap of 20 points so one noisy rule cannot dominate, then 100 − total deductions.

| Score | Grade | |---|---| | 75+ | Great | | 50–74 | Needs work | | < 50 | Critical |

Agent skill installation

npx -y rails-doctor@latest install              # installs skill for detected agents
npx -y rails-doctor@latest install --dry-run    # show what would be installed
npx -y rails-doctor@latest install --yes        # install for all without prompting

Detected: Claude Code (~/.claude/skills/), Codex (~/.agents/skills/), Cursor (~/.cursor/skills/), Windsurf, GitHub Copilot, OpenCode.

The skill teaches your agent the same rules rails-doctor enforces, so it writes correct Rails on the way in instead of being corrected after the fact.

GitHub Action

# .github/workflows/rails-doctor.yml
name: rails-doctor
on: [pull_request, push]
permissions:
  contents: read
  pull-requests: write
jobs:
  rails-doctor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: artisanscompany/rails-doctor@v0
        with:
          min-score: "75"
          comment-on-pr: "true"

The action posts a Markdown summary as a PR comment (updated in place on each push) and fails the build below min-score.

Deployment is intentionally not enforced

Kamal, Heroku, Fly, Render, Capistrano, Docker, Kubernetes — all fine. We score code, not your Procfile.

Philosophy

rails-doctor is opinionated about Rails code: routes, controllers, models, concerns, migrations, the Gemfile. It's lenient about infrastructure choices (deployment, multi-DB, queue backend, frontend stack) because those are project-level decisions that don't have a single right answer.

The default preset reflects 37signals/DHH conventions. If your team has chosen differently — Sidekiq instead of Solid Queue, RSpec instead of Minitest, Inertia instead of Hotwire — set allow: tokens in your config and rails-doctor will respect them.

Distribution

Distributed as an npm package. The package bundles the Ruby scanner source and a small Node wrapper that shells out to your system Ruby. No gem install, no Gemfile changes, no Bundler cache invalidation. Zero npm runtime deps; zero gem runtime deps (Ruby stdlib + built-in Prism).

License

MIT. Built by ArtisansCompany.