220개 이상의 언어에 대한 중복 코드 검출기 — 또한 데드 코드(dead code), 복잡성 핫스팟(complexity hotspots), 중복(duplication) 및 히스토리 동안의 건강 추세, 그리고 전체 코드베이스에 대한 하나의 건강 점수까지 제공합니다. Rust 엔진을 사용하며, 자체 포함형 바이너리이고, MCP 서버와 토큰 효율적인 리포터를 통해 AI 준비가 되어 있습니다.
jscpd는 지원하는 224개 형식 각각을 해당 언어가 정의하는 방식(일반 텍스트가 아닌 자체 주석 및 문자열 규칙)으로 토큰화한 다음, 이동식 Rabin-Karp 해시를 사용하여 파일 간의 중복된 토큰 시퀀스를 찾습니다. 옵트인 패스(Opt-in passes)는 이름이나 값만 다른 복사본(Type-2) 또는 몇 줄이 수정된 복사본(Type-3)을 포착하며, 실험적인 기능은 동일한 작업을 수행하지만 다르게 작성된 함수에 대해 코드 임베딩 모델을 사용합니다. 전체 메커니즘은 How detection works를 참조하고, 지원되는 형식 목록은 Supported formats를 참조하십시오.
-
언어 인식 토큰화(Language-aware tokenization) — 모든 224개 형식에 대한 포맷별 주석 및 문자열 구문을 지원하며, JavaScript/TypeScript/JSX/TSX용 oxc 파서, Vue, Svelte, Astro, Markdown, Razor를 위한 임베디드 언어 추출 기능, 그리고 키워드/식별자/리터럴 분류 기능을 제공합니다. 따라서 복제본은 텍스트의 반복된 실행이 아닌 언어 토큰의 반복된 시퀀스입니다 (작동 방식은 How detection works 참조).
-
224개 언어 형식을 지원하며, 교차 형식 감지(Vue SFC, Svelte, Astro, Markdown) 및 --cross-formats 그룹을 통해 JavaScript와 TypeScript 간의 복제본 일치를 수행합니다.
-
Type-2 클론 — --ignore-identifiers, --ignore-literals, 그리고 --ignore-annotations를 사용하면 이름, 리터럴 값 또는 주석에서만 차이가 나는 블록을 찾아 renamed로 보고합니다. 이름은 상대방의 하나의 이름을 대신해야 하므로, x = x + x는 d = a + b와 일치하지 않습니다. --ignore-identifiers=blind는 5.4 버전처럼 모든 이름을 일치시킵니다 ( docs 참조).
-
Type-3 근접 미스 클론(near-miss clones) — --max-gap-lines N은 몇 개의 삽입되거나 변경된 줄을 가진 복사본을 하나의 similar 클론으로 병합하고 유사도 점수를 부여합니다. --similarity는 Markdown 코드 블록 및 컴포넌트 내의 JavaScript, TypeScript, Python, Java, Kotlin, Scala, C#, Go, Rust, C, C++, PHP, Ruby, Swift, Clojure 전체 함수를 그들의 정규화된 구문 트리(normalized syntax trees) 서브트리별로 비교합니다. 이 과정에서 이름이 변경된 로컬 변수(각각 상대방의 하나의 이름을 대신함)와 다른 리터럴은 일치하지만, 호출된 다른 함수나 연산자는 일치하지 않으며 테스트 파일은 제외됩니다. edn 보고기는 점수와 함께 모든 쌍을 나열합니다 ( docs 참조).
-
Type-4 의미론적 클론 (실험적) — --semantic은 코드 임베딩 모델을 사용하여 JavaScript, TypeScript, Vue, Svelte, Astro, Python, Rust, Go, Java, Kotlin, C#, C, C++, PHP, Ruby, Scala 및 Swift 파일의 기능을 분석하며, 동일한 것을 다르게 작성하여 수행하는 함수를 보고합니다. 이는 하나의 언어에서 같은 기능이 두 번 구현된 경우이거나, 사용자의 Rust 백엔드에서 적용되는 규칙을 Svelte 프론트엔드가 반복하는 경우일 수 있습니다 (아래 의미론적 클론 참조).
-
포팅 진행 상황 및 동등성 (실험적): jscpd --compare python/ typescript/는 동일한 모델을 가진 두 폴더의 함수를 쌍으로 비교하고, 각 폴더의 어떤 함수가 다른 폴더에 대응하는 카운터파트(counterpart)가 있는지 목록화합니다. 이는 다른 언어나 플랫폼으로 포팅해야 할 부분이 무엇인지, 또는 앱의 Android 버전이 iOS 버전에 비해 부족한 기능이 무엇인지를 보여줍니다 (아래 두 코드베이스 비교 참조).
-
경계(Boundaries): .jscpd.json에 정의된 규칙은 모듈, 폴더, 파일 또는 메서드의 코드를 그 경계 내부에 유지합니다. 예를 들어, 오직 백엔드에서만 계산해야 하는 돈과 같은 경우입니다. 만약 이 규칙이 해당 코드를 제외하도록 설정한 곳에 복사본이 존재한다면, 누군가 이를 복사했든, 사본을 수정했든, 또는 다른 언어로 로직을 다시 작성했든 상관없이 실행에 실패합니다 (아래 경계 참조).
-
모든 곳의 클론 종류(Clone kinds everywhere) — 콘솔에서 exact, renamed 또는 similar로, JSON (kind, similarity, method), XML, HTML, Xcode, SARIF (jscpd/duplicate-code, jscpd/renamed-code, jscpd/similar-code, jscpd/similar-function, jscpd/semantic-code) 및 Code Climate 출력에서 지원합니다. 기본 실행은 여전히 exact 클론만 보고합니다.
-
--kind — 관심 있는 클론 종류만 유지할 수 있습니다: --kind renamed 또는 근접한 미스(near-miss) 클론만을 위한 --kind gap,ast를 사용합니다.
-
15개 리포터: console, console-full, json, xml, csv, html, markdown, badge, sarif, codeclimate, openmetrics, ai, xcode, threshold, silent
-
기준선 복제(Clone baseline) — 새로운 중복에 대해서만 CI 게이팅을 수행합니다. --baseline .jscpd-baseline.json --fail-on-new-clones[=N]은 레거시 클론을 허용하고 회귀 시 빌드를 실패시키며, --baseline-from-ref origin/main는 커밋된 파일 없이도 동일하게 작동합니다 (자세한 내용은 docs 참조).
-
변경한 파일만(Only the files you changed) — jscpd --changed .은 git status가 나열하는 파일을 대상으로 전체 프로젝트와 일치하는 클론을 보고하고, HEAD에 없었던 것을 새로운 것으로 표시합니다. --changed-only는 변경된 파일들끼리만 비교합니다. HEAD의 기준선은 첫 실행 시 저장되고 커밋 후 다시 빌드됩니다 (자세한 내용은 docs 참조).
-
게이팅 가능한 종료 코드(Exit codes you can gate on) — 알 수 없는 --format, 누락된 스캔 경로 또는 파일을 작성할 수 없는 리포터는 빈 보고서로 통과하는 대신 1을 반환하여 종료됩니다. --fail-on-empty는 파일 분석 결과가 없는 스캔을 실패시킵니다 (자세한 내용은 Exit codes 참조).
-
GitLab용 리포터(GitLab-ready reporters) — codeclimate (gl-code-quality-report.json)와 openmetrics (jscpd-metrics.txt)는 artifacts:reports에 플러그인됩니다.
-
사이드바이사이드 작성자 비교를 포함한 Git blame (--blame --reporters console-full)
-
--skip-local — 스캔 루트를 가로지르는 클론만 보고합니다: jscpd packages/api packages/web --skip-local은 각 트리 내부의 쌍은 무시하고 api에서 web으로의 중복만 유지합니다.
-
--skip-isolated — 서로 다른 팀이 소유한 모노레포 폴더 간의 중복을 무시합니다 (`--skip-isolated
-
--history — git 히스토리 전반의 중복 및 건강 추세 분석: jscpd --history는 현재 폴더를 기준으로 마지막 30개 커밋을 스캔하고, jscpd src --history v5.0.0..HEAD는 범위별 커밋(병합된 브랜치는 병합 커밋으로 간주)을 스캔합니다. 중복률과 건강 점수(health score)의 막대 차트를 출력하며, 커밋별 변화를 담은 표, 양 끝 지점에서의 각 건강 차원별 추세, 그리고 --threshold를 얼마나 더 강화할 수 있는지 등을 보여줍니다. 또한 --health와 --dashboard 옵션에서도 해당 시리즈를 출력합니다 (자세한 내용은 docs 참고).
-
--dead-code — 실행되지 않는 코드를 찾음: 단순히 두 번 작성된 코드뿐만 아니라, JavaScript, TypeScript, Python 전반에 걸쳐 사용되지 않은 파일, 내보내기(exports), 선언 및 가져오기(imports)를 찾아냅니다. 진입점(package.json, pyproject.toml, 프레임워크 컨벤션)으로부터 임포트 그래프를 구축하고 이를 순회하며 죽은 코드 연쇄 반응을 추적합니다. 즉, 호출하는 곳이 없는 헬퍼 함수는 그 자체로 보고되며, 각 발견 항목에는 신뢰도 점수가 함께 제공되고, 이 점수가 100점 미만일 경우 왜 잘못되었을 수 있는지에 대한 설명도 제공됩니다. 또한 독립적인 도구인 basta로도 배포됩니다 (자세한 내용은 docs 참고).
-
--summary — 스캔을 통해 얻는 리팩토링 핫스팟: 토큰, 라인 수, 크기별 상위 파일 및 폴더와 복잡도 추정치를 제공합니다 (자세한 내용은 docs 참고).
-
--complexity — 클론 검출 없이 순수하게 복잡도만 측정: 토큰화 과정을 거쳐 가장 복잡도가 높은 파일 및 폴더를 콘솔, ai, 또는 json 형식으로 출력합니다 (자세한 내용은 docs 참고).
-
--health — 중복되거나, 죽었거나(dead), 혹은 복잡한 파일에 집중된 코드의 비율을 기반으로 0점에서 100점 사이의 점수와 등급을 제공합니다. 크기 인식적이며, 42개의 오픈소스 프로젝트를 기준으로 보정되었고, --health-input 옵션을 통해 커버리지(coverage), 테스트 또는 보안 메트릭으로 확장할 수 있습니다.