Oxc로 자바스크립트 린팅과 포맷팅을 압도적으로 빠르게

Oxc로 자바스크립트 린팅과 포맷팅을 압도적으로 빠르게

자바스크립트 프로젝트를 하나 세팅하려면 설치해야 할 도구가 한두 개가 아닙니다. 코드 린팅에는 ESLint, 포맷팅에는 Prettier, 트랜스파일링에는 Babel이나 SWC, 번들링에는 Webpack이나 Vite… 각각 다른 팀이 다른 언어로 만든 도구들을 조합해서 쓰다 보니 설정 파일만 여러 개, 플러그인 간 버전 충돌에 빌드 속도는 답답하고. 😩

이 파편화된 자바스크립트 도구 생태계를 하나로 통합하겠다는 프로젝트가 있는데요, 바로 Oxc입니다. 이번 포스팅에서는 Oxc가 무엇이고, 어떤 도구들로 구성되어 있으며, 실제 프로젝트에 어떻게 도입할 수 있는지 알아보겠습니다.

Oxc란?

Oxc(The JavaScript Oxidation Compiler)는 Rust로 작성된 고성능 자바스크립트와 타입스크립트 툴체인입니다. 이름에서 “Oxidation”은 Rust의 상징인 산화(oxidation)에서 따온 것인데요, 자바스크립트 도구를 Rust로 다시 만들겠다는 의지가 담겨 있습니다.

Oxc는 VoidZero에서 개발하고 있습니다. VoidZero는 Vite의 창시자인 Evan You가 설립한 자바스크립트 도구 회사로, Vite뿐만 아니라 Vitest, Rolldown, Oxc까지 자바스크립트 생태계의 핵심 인프라를 관리합니다. 2026년 6월에는 Cloudflare가 VoidZero를 인수했는데요. 인수 후에도 Oxc를 비롯한 도구는 MIT 라이선스 오픈소스로 유지됩니다.

기존에도 Rust로 작성된 자바스크립트 도구가 있긴 했습니다. 트랜스파일링에는 SWC, CSS 처리에는 Lightning CSS가 있었는데요. 이 도구들은 각각 하나의 역할에 특화되어 있었습니다. Oxc는 여기서 한 발 더 나아가 파서, 린터, 포맷터, 트랜스포머, 리졸버, 미니파이어까지 자바스크립트 개발에 필요한 거의 모든 도구를 하나의 프로젝트 안에서 제공합니다.

어떤 도구들이 있을까?

Oxc는 여러 개의 독립적인 도구로 구성되어 있는데, 각각 어떤 역할을 하는지 간략히 살펴보겠습니다.

우선 모든 것의 기반이 되는 파서(oxc-parser)가 있습니다. 자바스크립트와 타입스크립트 파일을 추상 구문 트리(Abstract Syntax Tree, AST)로 변환하는 역할인데 공식 벤치마크에서는 SWC보다 3배 이상 빠릅니다. Test262 파서 테스트를 모두 통과하고 Babel과 TypeScript 파서 테스트도 99% 통과하여 정확도도 검증되었고요.

그다음으로 개발자들이 가장 직접적으로 쓰게 되는 린터(Oxlint)포맷터(Oxfmt)가 있습니다. Oxlint는 ESLint보다 50~100배 빠르고, Oxfmt는 Prettier보다 30배 빠릅니다. 이 두 도구는 뒤에서 자세히 다루겠습니다.

트랜스포머(oxc-transform)는 타입스크립트의 타입을 제거하고 JSX를 변환하거나 최신 문법을 ES2015까지 낮추는 역할을 합니다. React Compiler, React Fast Refresh, 데코레이터, styled-components 플러그인뿐만 아니라 타입스크립트 컴파일러 없이 격리된 선언(Isolated Declarations) 파일을 출력하는 기능도 지원합니다. 공식 벤치마크에서는 SWC보다 4배, Babel보다 40배 빠릅니다.

리졸버(oxc-resolver)는 모듈 경로를 해석하는 도구입니다. import 문에서 ./components/Button이라고 쓰면 실제로 어떤 파일을 가리키는지 찾아주는 건데 Webpack에서 쓰이는 enhanced-resolve보다 28배 빠릅니다.

마지막으로 미니파이어(oxc-minify)는 프로덕션 빌드에서 죽은 코드를 제거하고 문법을 더 짧게 바꾸며, 변수명을 축약하고 공백과 주석을 없앱니다. 독립 도구의 안정 버전 발표는 아직 없지만 Rolldown에서는 별도 설치 없이 기본 미니파이어로 쓰이고 있습니다.

Oxlint로 린팅하기

Oxlint는 2025년 6월에 안정 버전(v1.0)이 출시되면서 실전에서 쓸 수 있는 수준이 되었습니다. 840개 이상의 규칙이 내장되어 있는데 ESLint의 핵심 규칙뿐 아니라 typescript-eslint, eslint-plugin-react, eslint-plugin-import, eslint-plugin-unicorn 등 인기 플러그인의 규칙까지 포함합니다. 자바스크립트와 타입스크립트 외에도 Vue, Svelte, Astro 파일의 <script> 블록을 검사할 수 있어요.

설치부터 해보겠습니다.

bun add -D oxlint

package.json에 스크립트를 추가하면 바로 사용할 수 있습니다.

package.json
{
  "scripts": {
    "lint": "oxlint",
    "lint:fix": "oxlint --fix"
  }
}

oxlint 명령어만 실행하면 프로젝트 전체를 스캔하여 문제를 찾아줍니다. --fix는 프로그램의 동작을 바꾸지 않는 안전한 수정만 적용합니다. 동작이 달라질 수 있는 제안까지 적용하려면 --fix-suggestions, 위험한 수정까지 모두 허용하려면 --fix-dangerously를 명시해야 합니다.

그럼 실제로 얼마나 빠를까요? 공식 벤치마크에서는 CPU 코어 수에 따라 ESLint보다 50~100배 빠른 결과가 나옵니다. 기본 규칙 대부분을 Rust 네이티브 코드로 실행하고 여러 파일을 병렬로 검사하기 때문에 코드베이스가 커질수록 차이가 벌어지죠. 🤯

설정은 .oxlintrc.json이나 oxlint.config.ts 파일로 관리합니다. JSON 설정은 간단하고 어디서든 실행할 수 있습니다. 타입스크립트 설정은 defineConfig()의 타입 검사와 자동 완성을 받을 수 있고요.

.oxlintrc.json
{
  "$schema": "./node_modules/oxlint/configuration_schema.json",
  "rules": {
    "no-unused-vars": "warn",
    "no-console": "off",
    "eqeqeq": "error"
  },
  "ignorePatterns": ["dist", "node_modules"]
}

기본값으로는 잘못되었거나 쓸모없는 코드를 찾는 correctness 범주의 규칙이 켜집니다. 처음부터 모든 규칙을 활성화하기보다 이 기본값으로 시작한 뒤 프로젝트에 필요한 규칙을 조금씩 추가하는 편이 좋습니다.

안정화된 타입 인식 린팅

2026년 7월에는 타입 인식 린팅(type-aware linting)이 안정 버전에 도달했습니다. 타입을 알아야만 찾을 수 있는 처리되지 않은 Promise나 안전하지 않은 할당 같은 문제를 잡는 기능인데요. Oxlint가 파일 탐색과 일반 규칙을 처리하고 Go로 작성된 tsgolint가 typescript-go로 타입스크립트 프로그램을 만들어 타입 인식 규칙을 실행합니다.

타입 인식 린팅에는 별도 엔진이 필요합니다.

bun add -D oxlint oxlint-tsgolint@latest

설치한 뒤 명령줄에서 바로 켤 수 있습니다.

bunx oxlint --type-aware

매번 플래그를 붙이기 싫다면 루트 설정에 넣어두세요. typeAwaretypeCheck는 중첩 설정이 아니라 루트 설정에서만 사용할 수 있습니다.

oxlint.config.ts
import { defineConfig } from "oxlint";

export default defineConfig({
  options: {
    typeAware: true,
    typeCheck: true,
  },
  rules: {
    "typescript/no-floating-promises": "error",
    "typescript/no-unsafe-assignment": "warn",
  },
});

typeAware는 타입 정보가 필요한 규칙을 실행합니다. typeCheck까지 켜면 타입스크립트 컴파일러 진단도 린트 결과와 함께 보여주는데요. 두 작업이 같은 타입스크립트 프로그램을 공유하므로 CI에서 별도의 tsc --noEmit 단계를 대체할 수 있습니다. 다만 설정 레퍼런스에서는 아직 typeCheck를 실험 기능으로 표시합니다. 기존 타입 검사와 결과가 같은지 확인한 뒤 교체하는 편이 안전하겠죠.

안정 버전의 tsgolint는 typescript-eslint가 제공하는 타입 인식 규칙 61개 중 59개를 지원합니다. VS Code, TypeScript, TypeORM, Vue 코드베이스를 사용한 공식 벤치마크에서는 ESLint와 typescript-eslint 조합보다 12~18배 빨랐습니다. Darwin ARM64 기준 설치 용량도 29.7 MB에서 21.8 MB로 줄었습니다. 압축된 npm 다운로드는 13.1 MB에서 7.2 MB가 됐고요. 규칙별 실행 시간이 궁금하면 다음 명령어로 느린 규칙부터 확인할 수 있어요.

bunx oxlint --type-aware --debug timings

tsgolint는 TypeScript 7의 네이티브 Go 포트를 직접 사용하기 때문에 패키지 버전도 기반 TypeScript 버전을 따라갑니다. 예를 들어 7.0.2001은 TypeScript 7.0.2를 기반으로 한 tsgolint 패치 1을 뜻합니다. 타입 인식 린팅은 TypeScript 7 이상을 요구하며 baseUrl처럼 오래된 tsconfig.json 옵션은 지원하지 않습니다. 대규모 모노레포에서는 의존 패키지를 먼저 빌드해 선언 파일을 만들어야 합니다. 루트 tsconfig.json이 불필요한 파일까지 포함하지 않는지도 살펴보세요.

타입 인식 린팅과 별개로 여러 파일 분석(multi-file analysis)도 지원합니다. import 플러그인과 import/no-cycle 같은 규칙을 켜면 프로젝트의 모듈 그래프를 한 번만 만들어 공유하므로 순환 의존성 같은 문제를 효율적으로 찾을 수 있습니다.

에디터 지원도 넓어졌습니다. VS Code와 Cursor, Zed, IntelliJ IDEA와 WebStorm, Neovim에서 언어 서버 프로토콜(Language Server Protocol, LSP)을 통해 실시간 린팅 피드백을 받을 수 있습니다.

Oxfmt로 포맷팅하기

Oxfmt는 2026년 2월에 베타가 출시된 코드 포맷터입니다. Prettier의 자바스크립트와 타입스크립트 적합성 테스트를 100% 통과합니다. 최근 Prettier와 결과가 다르면 버그로 취급할 정도로 호환성을 중요하게 다루고 있어요.

설치 방법은 Oxlint와 동일합니다.

bun add -D oxfmt

package.json에 스크립트를 추가합니다.

package.json
{
  "scripts": {
    "fmt": "oxfmt",
    "fmt:check": "oxfmt --check"
  }
}

oxfmt 명령어를 인자 없이 실행하면 현재 디렉터리의 파일을 포맷팅합니다. --check 옵션을 사용하면 포맷이 맞는지만 확인하고요.

현재 공식 문서에서는 Prettier보다 약 30배, Biome보다 약 2배 빠르다고 설명합니다. 파일이 몇 개 없는 작은 프로젝트에서는 체감이 안 되겠지만 수천 개의 파일을 포맷팅하는 대규모 코드베이스의 CI에서는 차이가 커집니다.

Oxfmt가 특히 매력적인 건 Prettier에서는 별도의 플러그인이 필요했던 기능들이 내장되어 있다는 점입니다. import 정렬, Tailwind CSS 클래스 정렬, package.json 필드 정렬, CSS-in-JS와 GraphQL 포맷팅을 추가 플러그인 없이 사용할 수 있어요. 이 중 package.json 정렬만 기본으로 켜지고 import와 Tailwind CSS 클래스 정렬은 설정에서 직접 활성화해야 합니다.

지원하는 파일 형식도 놀라울 정도로 넓습니다. 자바스크립트, 타입스크립트, JSON, CSS, SCSS, Less, GraphQL, TOML은 Rust 네이티브 엔진으로 처리합니다. HTML, Angular, Vue, Svelte, Markdown, MDX, YAML, Handlebars, MJML은 Oxfmt 패키지에 포함된 Prettier로 처리하고요. 후자의 파일 형식도 별도로 Prettier를 설치할 필요는 없습니다. 그렇다고 모든 언어가 Rust로 포맷팅되는 건 아닙니다.

실제로 Vue.js, Turborepo, Hugging Face, Sentry JavaScript SDK 같은 유명 프로젝트들이 이미 Oxfmt를 쓰고 있습니다.

기존 도구에서 마이그레이션

이미 ESLint나 Prettier를 쓰고 있는 프로젝트에서 Oxc로 전환하는 방법을 살펴보겠습니다.

ESLint 9나 10의 플랫 설정을 사용한다면 @oxlint/migrate로 지원되는 규칙과 옵션, 파일별 재정의, 전역 변수, 무시 패턴을 옮길 수 있습니다.

bunx @oxlint/migrate eslint.config.js

타입 인식 규칙도 옮기려면 --type-aware를 붙입니다.

bunx @oxlint/migrate --type-aware

ESLint 플러그인 때문에 완전한 이전이 어렵다는 제약도 많이 줄었습니다. Oxlint의 자바스크립트 플러그인(JavaScript plugin)은 현재 알파 단계지만 ESLint 9 플러그인 API를 대부분 구현했습니다. 덕분에 네이티브로 옮겨지지 않은 기존 플러그인과 직접 작성한 규칙도 실행할 수 있어요. 자동 수정과 에디터 진단도 지원하고요. 다만 Vue나 Svelte 같은 사용자 정의 파일 형식과 타입 정보에 의존하는 사용자 정의 규칙은 아직 지원하지 않습니다.

기존 설정이 복잡하거나 지원되지 않는 플러그인이 남았다면 점진적으로 이전할 수 있습니다. Oxlint를 먼저 실행하고 ESLint에는 남은 규칙만 맡기세요. eslint-plugin-oxlint가 중복 규칙을 꺼줍니다.

bun add -D eslint-plugin-oxlint

플랫 설정에서는 Oxlint 설정을 배열 끝에 펼쳐 넣어야 합니다.

eslint.config.js
import oxlint from "eslint-plugin-oxlint";

export default [
  // 기존 ESLint 설정...
  ...oxlint.configs["flat/recommended"],
];
package.json
{
  "scripts": {
    "lint": "oxlint && eslint"
  }
}

ESLint 8의 .eslintrc 형식은 @oxlint/migrate가 직접 읽지 못합니다. 먼저 @eslint/migrate-config로 플랫 설정으로 바꾼 뒤 Oxlint 설정으로 옮겨야 합니다.

Prettier 설정도 전용 명령어로 변환하는 편이 안전합니다.

bun add -D oxfmt@latest
bunx oxfmt --migrate=prettier
bunx oxfmt

Oxfmt는 .prettierrc를 그대로 읽지 않고 .oxfmtrc.json, .oxfmtrc.jsonc, oxfmt.config.ts, oxfmt.config.mts 가운데 하나를 사용합니다. 마이그레이션 도구가 기존 옵션을 전용 설정으로 옮겨주지만 차이도 확인해야 하는데요. Oxfmt의 기본 printWidth는 100이라서 Prettier의 80과 다릅니다. Prettier 플러그인을 직접 실행할 수 없고 일부 실험 옵션도 아직 지원하지 않습니다. 기존 포맷 결과를 유지하려면 마이그레이션 뒤 생성된 설정에 printWidth: 80이 들어갔는지 확인하세요.

Vite 8과의 통합

Oxc는 단독으로 사용할 수도 있지만 Vite 8의 내부 엔진으로도 이미 채택되어 있습니다.

2026년 3월에 출시된 Vite 8은 자바스크립트와 타입스크립트 변환, 코드 압축을 Oxc가 담당하고 번들링은 역시 Rust로 작성된 Rolldown이 처리합니다. CSS 처리에는 Lightning CSS가 기본으로 사용되고요. 이렇게 빌드 파이프라인 전체가 Rust 기반 도구로 통일되면서 Rollup 대비 10~30배 빠른 빌드 속도를 달성했습니다. @vitejs/plugin-react v6도 React Fast Refresh 변환에 Oxc를 사용하면서 Babel 의존성을 제거했습니다.

Vite를 사용하고 있다면 이미 Oxc의 혜택을 받고 있는 셈입니다. 별도 설정 없이 Vite 8로 업그레이드하는 것만으로 Oxc의 빠른 파싱과 변환 성능을 누릴 수 있죠.

여기에 Oxlint와 Oxfmt까지 도입하면 린팅, 포맷팅, 트랜스파일링, 번들링, 압축까지 자바스크립트 빌드 파이프라인의 거의 모든 단계가 Rust 기반 도구로 구성됩니다. 각 도구를 따로 설치하고 싶지 않다면 Vite+ 통합 툴체인에서 Vite, Vitest, Oxlint, Oxfmt를 하나의 CLI로 사용할 수도 있습니다.

마치며

자바스크립트 도구 생태계가 빠르게 Rust 기반으로 재편되고 있습니다. SWC가 Babel을 대체하고, Lightning CSS가 PostCSS를 대체하기 시작한 것처럼, Oxc는 ESLint와 Prettier까지 아우르는 통합 툴체인으로 자리잡아 가고 있습니다.

특히 Oxlint는 일반 규칙뿐 아니라 타입 인식 린팅까지 안정화되면서 ESLint를 완전히 대체할 수 있는 프로젝트가 크게 늘었습니다. Oxfmt도 베타 단계이지만 자바스크립트와 타입스크립트에서 Prettier 호환성이 검증되어 있어서 도입 장벽이 낮고요. 다만 타입 인식 린팅의 TypeScript 7 요구 사항과 Oxfmt의 플러그인 및 기본값 차이는 마이그레이션 전에 꼭 확인해야 합니다. 대규모 프로젝트에서 린팅과 포맷팅에 시간이 오래 걸려 답답했다면 Oxc를 한 번 시도해보시는 걸 추천드립니다.

더 자세한 내용은 Oxc 공식 문서호환성 표를 참고하세요.

This work is licensed under CC BY 4.0CCBY

개발자를 위한 뉴스레터

달레가 정리한 AI 개발 트렌드와 직접 만든 콘텐츠를 전해드립니다.

Discord