Deno 2.0 완벽 가이드 — npm 호환·JSR·워크스페이스·성능·Node 비교·마이그레이션
이 글의 핵심
Deno 2.0은 Node·npm과의 상호 운용을 전제로 한 메이저 전환입니다. package.json·node_modules·워크스페이스를 이해하고, JSR과 npm 명세자(specifier)로 의존성을 설계한 뒤, 공식 벤치마크와 한계(V8 포인터 압축 등)를 함께 보며 마이그레이션 순서를 잡을 수 있습니다.
이 글의 핵심
Deno 2.0(2024년 10월 공개)은 “기존 JavaScript 인프라와의 호환”과 “단일 실행 파일로 제공되는 올인원 도구체인”을 동시에 노리는 메이저 릴리스입니다. 이 글에서는 주요 변경사항, package.json·node_modules·npm 워크스페이스와의 정렬, npm:·JSR(jsr:) 의존성 모델, deno install / deno add / deno remove, Deno 워크스페이스와 모노레포, 공개 벤치마크와 해석 시 주의점, Node.js와의 역할 비교, 1.x·Node에서 넘어올 때의 실전 마이그레이션 순서를 한 흐름으로 정리합니다.
선행 지식: ECMAScript 모듈(ESM),
package.json의 의존성 필드, 모노레포에서의 워크스페이스 개념을 알고 있으면 설명의 밀도를 온전히 활용할 수 있습니다.
1. Deno 2.0이 바꾼 전제
Deno 1.x가 URL·원격 import와 “설정 최소화”를 강하게 내세웠다면, Deno 2.0은 대규모·레거시·팀 단위 채택을 염두에 두고 Node·npm과의 호환 층을 정식 제품 기능으로 끌어올렸습니다. 그 결과 동일 코드베이스에서 기존 npm 자산을 그대로 소비하면서도, 필요할 때만 Deno 고유 기능(권한 모델, 내장 도구, deno compile 등)을 점진적으로 도입하는 그림이 현실적으로 됩니다.
1.1 주요 변경사항 요약
| 영역 | 내용 |
|---|---|
| Node·npm 호환 | package.json, node_modules, npm 워크스페이스 인식. ESM 중심 Node 프로젝트 실행·도구 병행 사용이 수월해짐 |
| 패키지 관리 | deno install, deno add, deno remove로 의존성 설치·갱신 (npm과 유사한 UX) |
| 레지스트리 | JSR(JavaScript Registry)을 공식 생태계 축으로 제시. 표준 라이브러리는 JSR @std에서 제공 |
| 비공개 npm | Node와 동일하게 .npmrc로 프라이빗 레지스트리·스코프 설정 |
| 워크스페이스 | deno.json의 workspace로 멀티 패키지 관리. npm 워크스페이스와 혼합 모노레포도 가능 |
| 도구 | deno fmt가 HTML·CSS·YAML까지, deno lint에 Node 규칙, deno test가 node:test 호환, deno task가 package.json 스크립트 실행 등 |
| 릴리스 모델 | LTS(장기 지원) 채널 도입(2.1부터). 기업 도입 시 안정성 논의에 활용 |
이 중 npm 호환과 JSR은 의존성 설계를 바꾸는 축이므로, 이후 절에서 개념을 분리해 설명합니다.
2. npm 패키지 호환성: 무엇이 “그대로” 되고 무엇이 조건부인가
Deno 2.0은 npm에 올라온 패키지를 Deno 런타임에서 해석할 수 있도록 모듈 해석·Node API 호환 층을 강화했습니다. 다만 모든 패키지가 수정 없이 동작한다는 뜻은 아니며, 특히 CommonJS 전용 가정, 특정 Node 내장 모듈의 엣지 케이스, 네이티브 애드온(Node-API)은 사전 검증이 필요합니다.
2.1 npm: 명세자(specifier): 매니페스트 없이 npm 쓰기
작은 스크립트나 노트북에서는 package.json 없이도 npm 패키지를 직접 가져올 수 있습니다. Deno는 이런 의존성을 전역 캐시에 두어, 저장소 루트에 node_modules를 만들지 않고도 실행할 수 있습니다.
// chalk 예시: 버전을 명세자(specifier)에 고정하면 재현성이 좋아집니다.
import chalk from "npm:[email protected]";
console.log(chalk.blue("Hello, world!"));
왜 필요한가: 빠른 실험·CI 일회성 스크립트에서 “프로젝트 뼈대 없이” 외부 라이브러리를 쓰기 위함입니다. 언제 한계가 오는가: 의존성 버전을 팀 전체가 동일하게 맞춰야 할 때는 deno.json의 imports나 package.json으로 옮기는 편이 안전합니다.
2.2 deno.json의 import map으로 bare import 정리
규모가 커지면 버전 문자열을 소스 곳곳에 두기 어렵습니다. deno.json에서 별칭을 두면 npm 패키지를 마치 일반 패키지 이름처럼 import할 수 있습니다.
{
"imports": {
"chalk": "npm:[email protected]"
}
}
import chalk from "chalk";
console.log(chalk.green("bare import"));
어떻게 동작하는가: Deno가 import map을 해석할 때 chalk를 npm:[email protected]으로 치환합니다. 주의점: 팀 규칙상 “락파일·재현 가능 설치”가 필요하면 deno install/package.json 기반 워크플로와 함께 쓰는지 여부를 CI 정책으로 명확히 하는 것이 좋습니다.
2.3 package.json과 node_modules를 “Node처럼”
Deno 2.0은 기존 Node 프로젝트 레이아웃을 이해합니다. 즉, 이미 package.json과 node_modules가 있는 저장소에서 의존성 설치·스크립트 실행·테스트를 Deno 관점에서 수행할 수 있습니다. 이는 “Deno만의 별도 우주”가 아니라 실제 팀 코드베이스에 끼워 넣기 위한 호환 전략입니다.
실무에서의 의미: 프론트엔드 빌드 체인·서버·CLI 중 일부만 Deno 도구(deno fmt, deno lint, deno test)로 바꾸는 점진적 도입이 가능해집니다. 반대로, 순수 Deno 프로젝트만 유지하고 싶다면 deno.json 중심으로 두고 npm은 필요한 패키지에만 제한하는 식으로 경계를 설계할 수 있습니다.
2.4 프라이빗 npm 레지스트리 (.npmrc)
기업 내부 스코프 패키지를 쓰는 경우, Node·npm과 동일하게 .npmrc에 레지스트리 URL과 인증 정보를 두면 Deno가 이를 활용합니다. 팀 보안 정책상 토큰은 환경 변수·시크릿 저장소로 주입하고, 저장소에 평문으로 커밋하지 않는 것이 전제입니다.
2.5 npm 호환의 내부 메커니즘(개발자가 알아야 할 것)
Deno 2의 npm 호환은 “Node를 그대로 복제”가 아니라, npm 패키지 메타데이터를 읽어 Deno 런타임이 이해하는 모듈 그래프로 재구성하는 층에 가깝습니다. 핵심은 다음과 같습니다.
- 해석기(resolver):
package.json의exports·imports·조건부 export를 따라 실제 파일 경로를 고릅니다. Node와 미묘하게 다른 해석이 나오면 엔트리 포인트·서브패스 export를 먼저 의심합니다. - CJS 상호 운용: CommonJS 모듈은 내부적으로 ESM 형태로 래핑되어 소비되는 경우가 많습니다. 이중 형식(dual package) 패키지는 타입·런타임 불일치가 드러나기 쉽습니다.
- 네이티브 애드온: N-API 의존 모듈은 플랫폼별 바이너리와 링크 방식에 민감합니다. CI 매트릭스(Windows/Linux/macOS)로 로딩 실패를 조기에 걸러야 합니다.
- 캐시:
npm:명세자로 가져온 패키지는 글로벌 캐시에 저장되어 재빌드 비용을 줄입니다. 반대로 캐시 무효화 전략이 없으면 “옛 버전이 남는다”는 이슈가 생깁니다.
3. JSR (JavaScript Registry)
JSR은 Deno 팀이 추진하는 현대적 JavaScript 패키지 레지스트리로, ESM만 허용, TypeScript 소스 배포, 다중 런타임·환경을 염두에 둔 메타데이터, 문서 자동 생성 등을 목표로 합니다. Deno 표준 라이브러리는 @std 스코프로 JSR에서 제공되며, npm만큼 거대하지 않지만 “검증된 기본 블록”을 빠르게 가져오기에 적합합니다.
3.1 npm과의 관계
- 소비: Deno에서는
jsr:명세자(specifier) 또는 설정으로 JSR 패키지를 가져올 수 있습니다. 팀 표준에 따라 npm 의존성과 혼합할 수 있습니다. - 배포: 라이브러리를 JSR에 올리면, JSR이 TypeScript를
.js·.d.ts등으로 변환해 소비자 환경 차이를 흡수하는 데 도움을 준니다(세부는 패키지 설정에 따름).
3.2 언제 JSR을 우선할까
다음에 가깝다면 JSR을 적극 검토합니다: 라이브러리가 Deno·Node·브라우저 등 여러 런타임에서 깨지지 않아야 하고, 패키지 메타데이터·문서 품질을 레지스트리 차원에서 맞추고 싶을 때. 반면 이미 npm 중심으로 게시·버저닝·조직 프로세스가 고정된 팀은, 당장은 npm을 유지하고 Deno는 소비자 런타임으로만 쓰는 편이 비용이 적을 수 있습니다.
4. Workspaces와 모노레포
Deno 2.0의 워크스페이스는 여러 하위 패키지를 한 저장소에서 일관되게 다루기 위한 기능입니다. 루트 deno.json에 멤버 디렉터리를 나열하는 형태가 기본 패턴입니다.
{
"workspace": ["./packages/add", "./packages/subtract"]
}
의도: 각 멤버는 자체 의존성·린트·포맷 설정을 가질 수 있어, 공용 코어와 앱·라이브러리를 한 repo에 두는 모노레포에 맞습니다.
4.1 npm 워크스페이스와의 혼합
Deno 2.0은 npm workspaces도 이해합니다. 따라서 일부 패키지는 package.json, 일부는 deno.json인 하이브리드 모노레포를 구성할 수 있습니다. 이는 “전사를 한 번에 Deno로 갈아타기”보다 팀·제품 단위로 경계를 나누는 현실적인 전략과 맞닿아 있습니다.
4.2 deno publish와 멀티 패키지
여러 멤버를 JSR 등에 게시할 때, 수동으로 순서를 맞추는 부담을 줄이기 위해 deno publish가 워크스페이스를 고려합니다(공식 예시·표준 라이브러리 구조 참고). CI에서는 버전 정책·변경 감지·게시 순서를 팀 규칙으로 문서화하는 것이 안전합니다.
5. 성능 벤치마크: 숫자를 “어떻게” 읽을 것인가
Deno 팀은 Deno 2.0 발표와 함께 패키지 매니저 성능과 HTTP 등 런타임 벤치마크를 제시했습니다. 여기서 중요한 것은 측정 조건(콜드/핫 캐시, OS, 버전)과 본인 워크로드와의 거리입니다.
5.1 deno install (공식 주장)
공식 자료에 따르면, deno install은 npm 대비 콜드 캐시에서 약 15%, 핫 캐시에서 약 90% 빠른 사례가 보고되었습니다. 이는 “의존성 해석·디스크 I/O·캐시 활용”이 겹친 결과이므로, 프로젝트 크기·락파일 유무·네트워크에 따라 체감은 크게 달라질 수 있습니다.
실무 해석: CI에서 캐시 전략을 세우는 팀에게는 유의미한 지표입니다. 로컬에서는 한 번 측정해 기존 npm/pnpm/yarn 파이프라인과 비교하는 것이 가장 정직합니다.
5.2 HTTP·처리량 벤치마크와 Deno 2.0 보정
공식 블로그에서는 과거 HTTP 벤치마크 그래프에 대해 Deno 2.0은 표시보다 약 20% 느릴 수 있다는 정정을 했습니다. 원인으로 V8 포인터 압축 비활성화(4GB 힙 한계를 넘는 사용자 사례 대응)가 언급되었고, 이후 포인터 압축 재활성화·대용량 힙이 필요한 빌드 분리(deno64 같은 방향)가 논의되었습니다.
시사점: 벤치마크는 특정 버전·빌드 옵션·워크로드에 묶입니다. API 게이트웨이를 Deno로 둘지, Node로 둘지는 지연 시간·메모리 프로파일·운영 팀의 친숙도를 함께 봐야 합니다.
5.3 기타 체감 포인트
- 시작 시간: 짧은 CLI·서버리스 스타일 작업에서 중요합니다.
- 단일 바이너리 도구체인: 별도
node_modules없이도 포맷·린트·테스트가 가능한 점은 온보딩 비용을 줄입니다. deno serve: 공식 자료에 따르면 멀티 코어 활용 등 서빙 측 개선이 포함되었습니다. 다만 이는 애플리케이션 코드·리버스 프록시 구성과 합쳐져야 의미가 있습니다.
6. Node.js vs Deno 2.0: 경쟁이 아니라 역할 분담
둘 다 V8(및 주변 스택)을 기반으로 JavaScript·TypeScript를 실행하지만, 제품 철학과 운영 모델이 다릅니다.
| 비교 축 | Node.js | Deno 2.0 |
|---|---|---|
| 생태계 중심 | npm·CJS 역사가 깊고, 도구·프레임워크의 기본 가정이 Node에 최적화된 경우가 많음 | npm·JSR을 소비할 수 있으나, 권한·내장 도구·웹 표준 API 쪽 가치 제안이 큼 |
| 보안 기본값 | 전통적으로 전역 권한(최근에도 --permission 실험 등 진행) | 옵트인 권한 모델이 강함. Node 호환 실행 시에도 동일 철학이 적용된다는 점이 공식 FAQ에 명시됨 |
| TypeScript | 외부 도구·빌드 단계가 일반적 | 네이티브 지원이 기본 스토리 |
| 배포 형태 | 서버·CLI·Electron 등 광범위 | deno compile 등 단일 실행 파일 배포 스토리가 강점 |
선택 기준 예시: 레거시 CJS·특정 네이티브 모듈에 깊게 묶인 서비스는 당분간 Node가 안전합니다. 새로운 마이크로서비스·내부 CLI·에지 근처 워커에서 권한 모델·도구 일원화를 노린다면 Deno 2.0을 후보에 둘 만합니다.
7. 실전 마이그레이션 가이드
아래는 Deno 1.x 또는 기존 Node(ESM) 프로젝트에서 옮길 때의 권장 순서입니다. 팀 상황에 맞게 단계를 쪼개는 것이 핵심입니다.
7.1 사전 점검
- 모듈 형식: ESM인가, CJS 혼합인가. CJS 비중이 높으면 리팩터링 범위를 먼저 산정합니다.
- 네이티브 의존성:
node-gyp·N-API 모듈이 있는지 확인하고, Deno에서의 지원 범위를 검증합니다. - 스크립트·CI:
package.json의scripts를deno task로 얼마나 대체할지 합의합니다.
7.2 도구부터 침투시키기
포맷·린트·테스트처럼 런타임과 분리하기 쉬운 영역부터 Deno 명령을 도입하면 리스크가 작습니다. 예: deno fmt, deno lint --fix, deno test(node:test 호환 활용).
7.3 의존성 정리
- npm 중심이면
deno install로node_modules를 구성하고, 문제가 되는 패키지를 목록화합니다. - Deno 중심이면
deno add/deno remove로package.json또는deno.json을 갱신하는 흐름을 표준화합니다.
7.4 권한 플래그 운영
로컬에서는 -A로 빠르게 열 수 있으나, CI·프로덕션에서는 --allow-net 등 최소 권한을 목표로 합니다. “작동은 하는데 배포만 실패”하는 경우 대부분 권한·파일 경로·환경 변수 불일치입니다.
7.5 공식 마이그레이션 문서
세부 API·플래그 변경은 릴리스마다 보강되므로, Deno 1.x → 2.x 마이그레이션 가이드를 버전에 맞춰 읽는 것을 권합니다.
8. 자주 겪는 문제와 점검 순서
npm:패키지가 런타임에서만 오류: 해당 패키지가 Node 내장 모듈 가정을 강하게 쓰는지, 조건부 export가 Deno 해석과 맞지 않는지 확인합니다.- 워크스페이스 간 의존성 꼬임: 루트와 멤버의
deno.json/package.json우선순위, 버전 범위를 정리하고, 락파일 전략을 하나로 맞춥니다. - 성능 회귀 체감: V8 빌드 옵션·메모리 한계 이슈는 버전 릴리스 노트와 함께 추적합니다. 프로덕션 전에는 부하 테스트로 확인합니다.
트러블슈팅 매트릭스
| 증상 | 1차 가설 | 확인 명령·행동 |
|---|---|---|
| 로컬에선 되고 CI만 실패 | 권한·환경 변수·캐시 차이 | deno run에 필요한 --allow-* 최소화 재현 |
| 특정 서브패스 import만 실패 | exports 해석 차이 | Node와 Deno에서 동일 엔트리로 최소 재현 |
| 네이티브 모듈 로딩 오류 | 플랫폼 바이너리·GLIBC | 해당 .node 의존성 제거 또는 대체 패키지 |
| 버전 고정인데도 코드가 변함 | 캐시·전역 설치 혼동 | deno clean(버전에 따라) 또는 캐시 경로 문서화 |
9. 정리
Deno 2.0은 “Deno만의 세계”와 “npm이 쌓아 온 현실” 사이를 잇는 릴리스입니다. npm:·package.json·deno install로 의존성 접근성을 확보하고, JSR로 차세대 모듈 게시·소비를 설계하며, 워크스페이스로 모노레포 운영을 단순화하려는 방향이 한데 모였습니다. 성능 수치는 캐시 상태·워크로드·버전에 민감하므로, 공식 벤치마크는 출발점으로만 두고 자신의 저장소에서 재측정하는 태도가 가장 안전합니다.
Node와의 선택은 기술 우열 한 방보다, 팀이 익숙한 운영·레거시 의존성·보안·배포 형태를 종합한 합의 결과에 가깝습니다. 이 글이 Deno 2.0 도입 논의의 공통 언어를 만드는 데 도움이 되기를 바랍니다.
참고
심화 부록: 구현·운영 관점
이 부록은 앞선 본문에서 다룬 주제(「Deno 2.0 완벽 가이드 — npm 호환·JSR·워크스페이스·성능·Node 비교·마이그레이션」)를 구현·런타임·운영 관점에서 다시 압축합니다. 도메인별 세부 구현은 글마다 다르지만, 입력 검증 → 핵심 연산 → 부작용(I/O·네트워크·동시성) → 관측의 흐름으로 장애를 나누면 원인 추적이 빨라집니다.
내부 동작과 핵심 메커니즘
flowchart TD A[입력·요청·이벤트] --> B[파싱·검증·디코딩] B --> C[핵심 연산·상태 전이] C --> D[부작용: I/O·네트워크·동시성] D --> E[결과·관측·저장]
sequenceDiagram participant C as 클라이언트/호출자 participant B as 경계(런타임·게이트웨이·프로세스) participant D as 의존성(API·DB·큐·파일) C->>B: 요청/이벤트 B->>D: 조회·쓰기·RPC D-->>B: 지연·부분 실패·재시도 가능 B-->>C: 응답 또는 오류(코드·상관 ID)
- 불변 조건(Invariant): 버퍼 경계, 프로토콜 상태, 트랜잭션 격리, FD 상한 등 단계별로 문장으로 적어 두면 디버깅 비용이 줄어듭니다.
- 결정성: 순수 층과 시간·네트워크·스케줄에 의존하는 층을 분리해야 테스트와 장애 분석이 쉬워집니다.
- 경계 비용: 직렬화, 인코딩, syscall 횟수, 락 경합, 할당·GC, 캐시 미스를 의심 목록에 둡니다.
- 백프레셔: 생산자가 소비자보다 빠를 때 버퍼·큐·스트림에서 속도를 줄이는 신호를 어디에 둘지 정의합니다.
프로덕션 운영 패턴
| 영역 | 운영 관점 질문 |
|---|---|
| 관측성 | 요청 단위 상관 ID, 에러율·지연 p95/p99, 의존성 타임아웃·재시도가 대시보드에 보이는가 |
| 안전성 | 입력 검증·권한·비밀·감사 로그가 코드 경로마다 일관적인가 |
| 신뢰성 | 재시도는 멱등 연산에만 적용되는가, 서킷 브레이커·백오프·DLQ가 있는가 |
| 성능 | 캐시·배치 크기·커넥션 풀·인덱스·백프레셔가 데이터 규모에 맞는가 |
| 배포 | 롤백 룬북, 카나리/블루그린, 마이그레이션·피처 플래그가 문서화되어 있는가 |
| 용량 | 피크 트래픽·디스크·FD·스레드 풀 상한을 주기적으로 검증하는가 |
스테이징은 데이터 양·네트워크 RTT·동시성을 프로덕션에 가깝게 맞출수록 재현율이 올라갑니다.
확장 예시: 엔드투엔드 미니 시나리오
앞선 본문 주제(「Deno 2.0 완벽 가이드 — npm 호환·JSR·워크스페이스·성능·Node 비교·마이그레이션」)를 배포·운영 흐름에 맞춰 옮긴 체크리스트입니다. 도메인에 맞게 단계 이름만 바꿔 적용할 수 있습니다.
- 입력 계약 고정: 스키마·버전·최대 페이로드·타임아웃·에러 코드를 경계에 둔다.
- 핵심 경로 계측: 요청 ID, 단계별 지연, 외부 호출 결과 코드를 로그·메트릭·트레이스에서 한 흐름으로 본다.
- 실패 주입: 의존성 타임아웃·5xx·부분 데이터·락 대기를 스테이징에서 재현한다.
- 호환·롤백: 설정/마이그레이션/클라이언트 버전을 되돌릴 수 있는지 확인한다.
- 부하 후 검증: 피크 대비 p95/p99, 에러율, 리소스 상한, 알림 임계값을 점검한다.
handle(request):
ctx = newCorrelationId()
validated = validateSchema(request)
authorize(validated, ctx)
result = domainCore(validated)
persistOrEmit(result, idempotentKey)
recordMetrics(ctx, latency, outcome)
return result
문제 해결(Troubleshooting)
| 증상 | 가능 원인 | 조치 |
|---|---|---|
| 간헐적 실패 | 레이스, 타임아웃, 외부 의존성, DNS | 최소 재현 스크립트, 분산 트레이스·로그 상관관계, 재시도·서킷 설정 점검 |
| 성능 저하 | N+1, 동기 I/O, 락 경합, 과도한 직렬화, 캐시 미스 | 프로파일러·APM으로 핫스팟 확인 후 한 가지씩 제거 |
| 메모리 증가 | 캐시 무제한, 구독/리스너 누수, 대용량 버퍼, 커넥션 미반납 | 상한·TTL·힙/FD 스냅샷 비교 |
| 빌드·배포만 실패 | 환경 변수, 권한, 플랫폼 차이, lockfile | CI 로그와 로컬 diff, 런타임·이미지 버전 핀 |
| 설정 불일치 | 프로필·시크릿·기본값, 리전 | 스키마 검증된 설정 단일 소스와 배포 매트릭스 표준화 |
| 데이터 불일치 | 비멱등 재시도, 부분 쓰기, 캐시 무효화 누락 | 멱등 키·아웃박스·트랜잭션 경계 재검토 |
권장 순서: (1) 최소 재현 (2) 최근 변경 범위 축소 (3) 환경·의존성 차이 (4) 관측으로 가설 검증 (5) 수정 후 회귀·부하 테스트.
배포 전에는 git add → git commit → git push 후 npm run deploy 순서를 권장합니다.
자주 묻는 질문 (FAQ)
Q. 이 내용을 실무에서 언제 쓰나요?
A. Deno 2.0의 Node·npm 호환, JSR 레지스트리, 모노레포 워크스페이스, deno install 성능, Node와의 차이, 1.x에서의 이전 절차를 실무 관점으로 정리합니다. 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.
Q. 선행으로 읽으면 좋은 글은?
A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.
Q. 더 깊이 공부하려면?
A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- [Deno 2 Complete Guide | Node.js Compatibility, npm, and JSR](/en/blog/deno-2-npm-compatibility-guide/
- [Deno Complete Guide | Secure JavaScript Runtime, Deno 2.0](/en/blog/deno-complete-guide-en/
- The Complete Deno Guide | Security, TypeScript, Standard Library, Deploy, and Production
이 글에서 다루는 키워드 (관련 검색어)
Deno, JavaScript, Runtime, npm, JSR 등으로 검색하시면 이 글이 도움이 됩니다.