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

fixearly

v0.4.0

Published

코드가 아니라 '다음에 고칠 때 드는 비용'을 잰다 — 일찍 고치면 싸다. JS/TS 정적 분석, 100% 로컬, SSS~E 등급, 오픈소스 70개 기준선

Readme

fixearly

fixearly

우리 엔진도 B입니다. 2천 줄 단일 파일이라서요. 툴은 자기한테도 안 봐줍니다 — 그게 요점입니다. (랜딩)

코드가 아니라 그 코드를 다음에 고칠 때 드는 비용을 잰다. JS·TS 전용 · 정적 분석 · 100% 로컬 · LLM 0 · SSS ~ E 등급.

npx fixearly --dir=src --report

명령 한 줄, 설정 제로. 코드는 컴퓨터 밖으로 한 발짝도 안 나간다. --report한 장짜리 HTML을 뽑는다 — 같은 체급 오픈소스 안에서 내 위치, 축별 좌표, 무엇부터 고칠지(파일:줄), 그리고 각 항목을 코딩 에이전트에 그대로 붙여넣을 작업 지시문까지.

등급: B (73점) — 함수 11,000개, cog15+ 293개, 중복 5.5%, 200줄+ 173개
지난 측정(2026-07-20 09:00) 대비: C 69 → B 73 (+4점)
✓ 리포트 → fixearly-report.html

유명 오픈소스 70개, 실제 점수

같은 자로, 예외 없이 채점했다. 2026-07-26 · 채점 규칙 v6 기준 전량 재측정. 전체는 랜딩에.

| 프로젝트 | 등급 | 점수 | 핵심 지표 | |----------|------|------|-----------| | mitt | SSS | 100 | 1파일 · 75줄 · 중복 0% | | rxjs | SSS | 99 | 188파일 · 6,536줄 · 중복 6.5% | | execa | SSS | 98 | 103파일 · 5,726줄 · 중복 0.7% | | discordjs | SS | 95 | 695파일 · 37,164줄 · 중복 6.3% | | nestjs | SS | 95 | 483파일 · 31,726줄 · 중복 7.3% | | cypress | SS | 93 | 226파일 · 26,436줄 · 중복 1% | | trpc | SS | 93 | 70파일 · 7,295줄 · 중복 2.2% | | prisma | SS | 93 | 147파일 · 9,287줄 · 중복 1.2% | | mongoose | D+ | 52 | 긴 함수 6.1% · 중복 5.7% | | lexical | D+ | 50 | 긴 함수 7.4% · 중복 1.3% | | vue | D | 40 | 긴 함수 8.1% · 중복 1.1% | | payload | D | 39 | 긴 함수 15.5% · 중복 5.5% | | react | E+ | 28 | 긴 함수 10.1% · 중복 18.8% |

react가 E+다. 이건 "나쁜 라이브러리"라는 뜻이 아니다. 성능과 번들 크기를 위해 추상화를 일부러 포기한 코드 (모노모픽 메가함수, 빌드 타깃별 손복제)를 이 축이 깎기 때문이다. 실제로 react-devtools를 제외하면 점수가 내려간다 — 툴링이 완충재였다. 점수는 판결이 아니라 측정이다. 무엇을 재는지 전부 아래에 공개한다.


무엇을 재는가

채점축 4개 (등급을 만든다 · 캡 기준 배점)

| 축 | 배점 | 설명 | |----|------|------| | 함수 길이 | 26 | 한 번에 읽어야 하는 양. 중첩 함수·주석을 뺀 자기 코드 줄 기준, 40줄 초과(JSX 60줄) 비율 + p90 + 상위 10개 평균. 파일을 쪼개도 안 변하므로 조작이 안 된다. | | 인지 복잡도 | 37 | SonarSource S3776 스펙 준수(정본값 일치 검증). cog15+·cog25+ 비율 + p90 + 상위 10개 평균. | | 중복 | 9 | 토큰 단위 복붙 밀도. 70개 실측에서 점수와 상관 −0.11이라 배점을 16→9로 낮췄다 — 대부분엔 0점, 소수에게만 큰 항목. | | 파일 크기 | 8 | 평균 줄 수 + 대형 파일 비중. 27→8로 강등했다: 같은 코드를 6파일로 쪼개기만 해도 옛 공식이 +27점을 줬다. |

상위 10개 평균을 쓰는 이유: 최악값 1개를 재면 "가장 나쁜 하나만 고치고 끝"이 최적 전략이 된다(실측: 하나 고치면 +0.99점, 그 다음부터 ~0). 상위 10개 평균은 10개를 실제로 줄여야 계속 내려간다.

진단 17종 (등급을 건드리지 않는다 · 파일:줄만 짚는다)

O(n²) 배열 조회 · 루프 안 파일 IO/N+1 · await in forEach · 스프레드 누적 O(n²) · 루프 안 new RegExp · 공유 참조 fill · 빈 catch · 타입 위생(any·non-null·@ts-ignore) · 데드코드(--dead, knip) 외.

왜 점수에서 뺐나: O(n²)n이 실제로 큰지 사람이 확인해야 의미가 있다. 사람 판단이 필요한 축을 자동 채점에 넣으면 작은 저장소가 통째로 무너진다. 그래서 "고칠 목록"으로만 낸다.


왜 믿나 — 점수는 방어할 수 있어야 점수다

  • 한계를 먼저 밝힌다JS·TS 전용. 파서가 TypeScript 컴파일러 API라 .ts .tsx .js .jsx .mjs .cjs만 읽는다. 그리고 설계의 우아함·테스트·문서·보안·성능·커뮤니티는 하나도 재지 않는다.
  • 게이밍을 측정해서 공개한다 — 같은 코드를 함수 경계에서 6파일로 기계 분할: 옛 공식 +27점 → 지금 +8점(파일 축 캡). 5줄짜리 파일 대량 투입은 분석 제외로 막힌다. 다만 "게임 불가"라고 주장하지 않는다 — 남은 구멍(파일 축 8점)을 여기 적어두는 편이 정직하다.
  • 오픈소스 70개로 보정 — 유예값은 임의 임계가 아니라 코퍼스 중앙값이고, 기울기는 p90에서 캡에 닿게 잡았다. (중앙 81)
  • 체급은 코드줄로 나눈다 — 파일 수로 나누면 파일을 잘게 쪼갠 쪽이 체급만 올라간다(실측: 줄/파일이 34~2,008로 59배 차이).
  • 종류별 편향을 공개한다 — 라이브러리 87 · 프레임워크 85 · 툴체인 84 · 앱 76 · 엔진·컴파일러 66. 엔진은 추상화를 포기하고, 앱은 화면 단위 함수가 길다. 편향이 아니라 이 축의 성격이다. 그래서 리포트는 동종 기준선을 함께 보여준다.
  • 채점 규칙에 버전을 박았다 — 유예·기울기를 바꾸면 v6 → v7. 이력 비교 시 규칙이 다르면 "점수 비교 무효"를 경고한다.
  • 네거티브 컨트롤 · 자기 검증 루프 · 패턴 카탈로그LOOP.md · PATTERNS.md
  • 실전 검증 — 등급만 매기지 않고 진짜 고칠 것을 짚는다. 실제 OSS에 낸 PR 기록: IMPACT.md

사용법

# 리포트 한 장 (권장) — 내 위치 + 고칠 목록 + AI 지시문
npx fixearly --dir=src --report

# 점수만
npx fixearly --dir=src

# 먼저 고칠 파일 랭킹 (복잡도 × git churn)
npx fixearly --dir=src --hotspots

# 데드코드 축 추가 (knip 내장)
npx fixearly --dir=src --dead

# 모노레포에서 산출물 아닌 패키지 제외 (근거를 남길 것)
npx fixearly --dir=packages --exclude=packages/devtools,packages/examples

# README 배지
npx fixearly --dir=src --badge

측정할 때마다 .fixearly-history.json에 스냅샷이 쌓이고, 리포트에 지난번 대비 변화가 표시된다. 점수는 절대 위치, 변화량은 당신이 한 일이다 — 자기 이력과의 비교라 지표만 건드려서는 움직이지 않는다.

결과는 --out 디렉토리에 kit-stats.json으로도 떨어진다 (CI 추이 추적용).


등급

| 등급 | 점수 | | 등급 | 점수 | |------|------|---|------|------| | SSS | ≥ 97 | | C+ | ≥ 64 | | SS | ≥ 93 | | C | ≥ 55 | | S | ≥ 90 | | D+ | ≥ 47 | | A+ | ≥ 86 | | D | ≥ 35 | | A | ≥ 80 | | E+ | ≥ 21 | | B+ | ≥ 76 | | E | ≥ 0 | | B | ≥ 70 | | | |

등급은 아래쪽을 후하게 잡았다 — 큰 서비스·앱은 구조 지표상 원래 불리하다. E는 사실상 방치된 경우만.


라이선스

MIT