이롭게 현명하게

[IT노트] 패키지 매니저란? / npm, yarn, pnpm 정리 본문

IT 노트

[IT노트] 패키지 매니저란? / npm, yarn, pnpm 정리

dev_y.h 2026. 4. 29. 18:10
728x90
반응형

패키지 매니저란?

 


 

목차

 

패키지 매니저가 필요한 이유

패키지 매니저란?

패키지 매니저의 동작 원리

Link 방식에 따른 차이

npm, yarn, pnpm 한눈에 비교

왜 여러 패키지 매니저가 존재할까?

정리


 


[패키지 매니저가 필요한 이유]

패키지 매니저는 프로젝트에서 라이브러리, 프레임워크, 모듈 등의 패키지를 관리하는 도구다.

필요한 패키지를 설치, 업데이트, 삭제, 설정할 수 있도록 도와준다.

자바스크립트에서는 npm, yarn, pnpm 등이 대표적이다.

 

<자바스크립트에서 패키지 매니저가 필요한 이유>

문제 상황 : 경로만 쓰면 버전이 모호하다.

자바스크립트/타입스크립트에서 외부 라이브러리를 가져올 때 개발자는 'react'와 '@toass/utils'처럼 간단히 라이브러리 이름만 작성한다.

import React from 'react';
import { sum } from '@toss/utils';

 

하지만 컴퓨터는 이 파일을 어디서 가져와야 하는지, 어떤 버전의 라이브러리를 사용해야 하는지 모른다.

자바스크립트 표준에서는 라이브러리를 가져올 때 정확한 경로를 알아야 하기 때문이다.

예를 들어 React 라이브러리는 18 버전과 19 버전이 있다.

'react'라고만 작성해 두면 컴퓨터는 어떤 버전을 사용해야 할지 모른다.

버전과 경로를 매번 직접 명시하면 해결할 수 있겠지만 개발 과정에서 긴 경로를 계속 작성하는 것은 번거로운 일이다.

 

해결책 : package.json

이러한 문제를 해결하기 위해 package.json에 필요한 라이브러리와 버전 범위를 명시해 둔다.

{
  "dependencies": {
    "react": "^18.2.0"
  }
}

"^18.2.0" : 18.2.0 이상, 19 버전 미만

그리고 설치된 라이브러리는 우리가 코드에서 import React from 'react'라고 썼을 때 자동으로 연결되어 사용할 수 있게 된다.

 

이렇게 라이브러리를 정확한 버전으로 설치할 수 있도록 도와주는 것이 패키지 매니저다.

 


[패키지 매니저란?]

패키지 매니저는 package.json에 적힌 라이브러리를 정확한 버전으로 설치하고 코드에서 문제없이 불러올 수 있도록 연결해 준다.

출처 : https://toss.tech/article/lightning-talks-package-manager -> yarn을 터미널에 실행했을 때 볼 수 있는 화면

 

 


[패키지 매니저의 동작 원리]

패키지 매니저가 동작하는 세 단계가 있다.

  1. Resolution 단계
    • 라이브러리 버전 고정
    • 라이브러리의 다른 의존성 확인
    • 라이브러리의 다른 의존성 버전 고정
  2. Fetch 단계
    • 결정된 버전의 파일을 다운로드하는 과정
  3. Link 단계
    • Resolution/Fetch 된 라이브러리를 소스코드에서 사용할 수 있는 환경을 제공하는 과정

 

<Resolution 단계>

Resolution 단계는 package.json에 적힌 범위를 실제 설치할 구체적인 버전으로 확정하고 모든 의존성과 그 하위 의존성까지 버전을 고정해 lock파일에 기록하는 과정이다.

모든 기기에서 고정된 버전을 사용할 수 있도록 한다.

의존성 버전을 전부 고정시키고 의존성의 의존성을 다 찾아서 그 버전도 고정시켜 yarn.lock이나 package-lock.json에 저장한다.

 

버전을 고정하기 위해서는 세 가지의 단계를 거쳐야 한다.

  1. 라이브러리 버전 고정
  2. 라이브러리의 다른 의존성 확인
  3. 라이브러리의 다른 의존성 버전 고정

 

[Resolution 1. 라이브러리 버전 고정]

첫 번째 단계에서는 package.json에 명시된 라이브러리 버전 범위를 실제 버전으로 확정하는 단계다.

package.json에는 버전의 범위가 적혀있다.

패키지 매니저는 이 범위 안에서 가장 적절한 버전을 딱 하나 골라야 한다.

{
  "dependencies": {
    "react": "^18.2.0"
  }
}

예를 들어 react:^18.2.0이라고 적혀있다면 18.2.0 이상 19 미만이라는 뜻이다.

보통은 가장 최신 버전을 선택한다.

그래서 실제 설치는 최신 버전인 18.3.1을 선택할 수 있다.

 

[Resolution 2. 라이브러리의 다른 의존성 확인]

두 번째 단계는 의존성의 의존성을 확인한다.

자바스크립트에서는 패키지끼리 의존성을 갖는 상황이 흔하다.

예를 들어 @toss/use-overlay라는 라이브러리는 내부적으로 react를 필요로 한다.

그런데 react도 또 다른 의존성이 있을 수 있다.

즉 설치한 라이브러리가 또 다른 라이브러리를 요구하고 그 라이브러리가 또 다른 걸 요구하는 "의존성 체인"이 생긴다.

그래서 의존성이 또 어떤 의존성을 가지는지 확인하는 작업이 필요하다.

Resolution 단계에서는 이런 "줄줄이 딸려 오는" 의존성들을 전부 확인한다.

 

[Resolution 3. 라이브러리의 다른 의존성 버전 고정]

마지막 세 번째 단계는 모든 의존성 버전을 고정한다.

즉 팀원 모드 환경에서 동일한 버전을 사용 가능하도록 lock파일을 생성하는 단계다.

(package-lock.json, yarn.lock, pnpm-lock.yaml)

자바스크립트에서는 의존성의 버전을 범위로 명시하고 패키지 간에도 의존성을 가지기 때문에 똑같은 package.json에 대해서도 사용하는 의존성 버전이 완전히 달라질 수 있다.

왜냐하면 package.json에는 범위만 적혀있어서 같은 프로젝트라도 누가 설치하느냐에 따라 버전이 달라질 수 있다.

예를 들어 내 컴퓨터에서는 React 18.1.0이 설치되었는데

동료 컴퓨터에서는 React 18.2.0이 설치될 수 있다.

이렇게 되면 같은 코드를 실행했는데 내 컴퓨터에서는 잘 되고 다른 동료 컴퓨터에서는 버그가 생길 수도 있다.

 

<Fetch 단계>

Fetch 단계에서는 Resolution에서 고른 정확한 버전의 패키지를 실제로 다운로드하는 과정이다.

예를 들어 Resolution에서 React 18.3.1을 사용하자고 결정했다면 패키지 매니저가 npm 서버(레지스트리)에 가서 React 18.3.1 압축 파일을 받아온다.

이 과정을 거쳐야 내 컴퓨터 안에 실제로 React, Next.js 같은 라이브러리 파일들이 생긴다.

내 코드에서 import React from 'react'라고 했을 때 정상적을 동작할 수 있다.

 

<Link 단계>

Linker 단계는 내 코드에서 import/require가 잘 동작하도록 설치한 라이브러리를 어떻게 연결할지 정하는 과정이다.

Resolution/Fetch 된 라이브러리를 소스코드에서 사용할 수 있는 환경을 제공하는 과정이다.

즉 내 코드에서 라이브러리를 실제로 쓸 수 있게 연결해 주는 과정이다.

이때 패키지 매니저(npm, yarn, pnpm, PnP : Plug n Play)마다 방식을 다르게 가져간다.

 

 


[Link 방식에 따른 차이]

  1. npm Linker
  2. pnpm Linker
  3. yarn PnP Linker

 

1. npm Linker(node_modules)

npm은 설치한 라이브러리를 node_modules 폴더에 그대로 복사해서 넣는 방법을 사용한다.

그래서 라이브러리를 설치할수록 폴더가 커진다.

같은 라이브러리를 여러 프로젝트에서 사용하면 중복 설치가 발생한다.

예를 들어 100개 프로젝트에서 React 18.2.0을 사용한다면 React가 100번 설치된다.

import나 require를 할 때, Node.js가 node_moduls를 계속 위로 올라가며 찾아야 해서 속도가 느려질 수 있다.

 

2. pnpm Linker

이런 단점들 때문에 pnpm(performant npm)이 생겨났다.

똑같이 node_modules를 사용하지만 라이브러리를 실제로 복사하지 않고 바로가기(하드링크 : HardLinker)만 걸어둔다.

그래서 속도도 더 빠르고 디스크 용량도 덜 차지한다.

대신 npm 보다는 낫지만 여전히 node_modules가 필요하다는 한계가 있다.

 

3. yarn PnP Linker

yarn PnP Linker라고 해서 yarn과 PnP는 다른 패키지 매니저라고 생각할 수 있다.

yarn : 패키지 매니저 이름으로 npm과 같은 역할을 한다.

PnP : yarn에서 제공하는 라이브러리 연결(Link) 방식 중 하나다.

즉 yarn에는 node_modules 방식과 pnp 방식으로 두 가지 Link 방식이 있다.

  • 기본 yarn : node_modules 폴더 사용
  • yarn PnP : node_modules 없이 .pnp.cjs라는 Map 파일을 만들어 메모리에서 의존성을 바로 연결

패키지를 설치하면 node_modules 폴더가 생긴다.

npm, pnpm은 이 node_modules를 만들어서 파일들을 넣는다.

그런데 yarn의 PnP 방식은 다르다.

yarn install을 하면 node_modules 폴더를 만들지 않는다.

그래서 디스크 용량을 덜 차지한다.

대신 .pnp.cjs라는 "지도(Map)"파일을 하나 만든다.

여기에는 "React는 18.2.0 버전은 여기에 있어요!(= 사용해요!)" 같은 정보가 적혀있다.

Node.js가 import React 같은 걸 실행할 때 node_modules 폴더에서 찾아야 하는데 .pnp.cjs 파일에서 보고 위치로 이동한다.

폴더를 만들지 않아도 되어 설치 속도는 빠르다.

Map의 역할을 하는 .pnp.cjs만 보면 되어서 실행속도는 빠르다.

단점은 호환성이 낮다.

yarn PnP는 node_modules가 없기 때문이다.

많은 도구들이 node_modules폴더가 반드시 있을 거라 가정하고 만들어진다.

하지만 PnP에는 node_modules가 없어서 문제가 생길 수 있다.

 

<요약>

  • npm : 전부 복사해서 node_modules에 넣는다.(느리고 무겁다)
  • pnpm : 복사 대신 "바로가기"를 걸어서 효율적으로 관리(빠르고 가볍다)
  • yarn PnP : node_modules 자체를 없애버리고 Map 파일로 관리(초고속, 하지만 호환성 문제가 있다.)

 


[npm, yarn, pnpm 한눈에 비교]

 

1. npm이란?

npm install react

Lock 파일 : package-lock.json

개요

npm(Node Package Manager)은 자바스크립트 패키지 매니저이다.

사용할 수 있는 모듈들을 패키지화하여 모아두는 장소 역할과 패키지 설치 및 관리를 위한 CLI를 제공한다.

프로젝트에서 필요한 라이브러리를 설치하고 버전을 관리하며 의존성을 쉽게 다룰 수 있다.

 

주요 특징

  • node_modules 폴더에 라이브러리를 복사하는 방식으로 설치
  • 설치 시 package.json의 범위를 기준으로 정확한 버전을 결정
  • package-lock.json 파일을 통해 동일한 버전으로 설치할 수 있도록 돕는다.
  • 대부분의 Node.js 패키지 호환이 가능하다.

 

장단점

장점

  • 안정적이고 호환성이 좋다.
  • Node.js 공식 도구라 별도 설치 없이 바로 사용할 수 있다.
  • 패키지를 설치할 때 의존성도 자동으로 설치된다.
  • package.json 파일 내의 스크립트 섹션을 통해 자동화 작업이 가능

단점

  • 디스크 공간을 많이 사용한다.(중복 설치 발생)
  • 대규모 프로젝트에서 node_modules폴더가 매우 커질 수 있다.
  • 설치 속도가 yarn, pnpm보다 느리다.

 


2. yarn 이란?

yarn add react

Lock 파일 : yarn.lock

 

개요

Facebook(현 Meta)에서 npm의 단점을 개선하기 위해 만든 자바스크립트 패키지 매니저이다.

빠른 설치 속도와 안정적인 버전 관리를 목표로 만들어졌다.

npm과 호환된다.

대규모 프로젝트에서도 패키지 의존성을 더 효율적으로 관리할 수 있게 해 준다.

 

주요 특징

  • yarn.lock 파일을 사용해 모든 개발자가 동일한 라이브러리 버전 설치
  • 병렬 다운로드와 캐싱으로 설치 속도 개선
  • npm과 거의 동일하게 동작하여 대부분의 라이브러리 호환

 

장단점

장점

  • 캐싱 기능으로 설치 속도가 npm보다 빠르다.
  • yarn.lock 파일을 통해 모든 개발 환경에서 동일한 패키지 버전을 보장
  • 단일 레포지토리 내에서 여러 패키지를 관리할 수 있어 모노레포에서 유용
  • checksum을 통해 패키지의 무결성을 확인하여 설치 과정의 신뢰성을 높인다.
  • 플러그인 시스템 제공

단점

  • 일부 오래된 Node.js 환경에서 호환성 문제가 있다.
  • node_modules 구조를 여전히 사용하므로 디스크 최적화는 제한적
  • npm 보다 약간 복잡할 수 있다.

 


3. pnpm(Performant npm) 이란?

pnpm add react

Lock 파일 : pnpm-lock.yaml

개요

pnpm은 npm과 yarn 보다 디스크 공간과 설치 속도를 최적화한 패키지 매니저이다.

Hard Link를 사용해 라이브러리를 한 번만 설치하고, 각 프로젝트에서 공유하도록 설계되어 있다.

 

주요 특징

  • node_modules 구조를 유지하면서 디스크 사용량 최소화
  • 속도 빠르고 큰 프로젝트에서 효율적
  • 패키지를 중복으로 설치하지 않고, Hard link를 사용하여 디스크 공간을 절약하고 설치 속도를 높여준다.
  • 대규모 프로젝트에서의 성능 향상과 더불어 디스크 공간도 효율적으로 사용할 수 있다.

 

장단점

장점

  • 중복된 패키지를 제거하여 디스크 공간 절약
  • 설치 속도가 빠름
  • pnpm-lock.yaml 파일을 통해 모든 개발자 환경에서 동일한 패키지 버전을 보장
  • 프로젝트별로 의존성을 격리하여 서로 영향을 주지 않도록 한다.
  • 프로젝트마다 같은 라이브러리 버전을 보장
  • 패키지를 중복으로 설치하지 않고, 하드 링크를 사용하여 빠르고 효율적으로 패키지를 관리
  • 모노레포를 지원하여 여러 프로젝트를 단일 레포지토리에서 관리할 때 효율적

단점

  • 일부 구형 라이브러리나 툴에서 호환성 문제 발생 가능
  • npm/yarn에 비해 상대적으로 덜 알려져 있다.

 


[왜 여러 패키지 매니저가 존재할까?]

패키지 매니저는 의존성을 관리하는 방식에 따라 차이가 있다.

모든 상황에 맞는 하나의 정답은 없고 프로젝트의 성격, 팀 문화, 개발 환경에 맞춰 도구를 선택하는 것이 중요하다.

운영체제와 언어 환경이 다르면 설치 방식과 의존성 처리, 빌드 환경 요구사항도 달라진다.

그래서 각각에 맞는 도구가 필요하다.

예 : pip vs conda

  • pip : Python 패키지 중심
  • conda : Python 뿐 아니라 시스템 라이브러리까지 관리 가능(데이터 과학에서 선호)

예 : npm vs yarn vs pnpm

  • npm : 유연하지만 일부 상황에서 의존성 충돌 가능
  • yarn : 더 엄격하게 버전을 고정하고 빠른 설치와 캐싱 지원
  • pnpm : 대규모 프로젝트에서 디스크 공간을 절약하고 설치 속도를 개선

 

<어떤 패키지 매니저를 사용해야할까?>

npm은 호환성이 중요하거나 작은 프로젝트에서 사용한다.

yarn은 안정적인 버전관리와 빠른 설치 속도를 제공하여 중간 규모의 프로젝트에 사용한다.

pnpm은 대규모 프로젝트에서 디스크 공간을 절약하고 설치 속도를 개선하기 위해 사용한다.

 

패키지 매니저가 여러개인 이유는 통일하지 못해서가 아니라 각기 다른 목적과 환경에 맞게 발전해 왔기 때문이다.

 


[정리]

  • 목적과 설계 철학 차이 : 속도, 안정성, 디스크 효율, 호환성 등
  • 팀 문화, CI/CD 환경, 프로젝트 요구사항에 따라 선택
  • 운영체제와 언어 환경 차이도 고려 필요

예시 : Python

  • pip : Python 패키지 중심
  • conda : Python + 시스템 라이브러리 관리

예시 : JavaScript

  • npm : 호환성과 안정성 중시, 작은 프로젝트 적합
  • yarn : 빠른 설치와 안정적 버전 관리, 중규모 프로젝트 적합
  • pnpm : 성능과 디스크 효율, 대규모 프로젝트 적합

 

  • npm
    • 가장 널리 사용되며, 기본적인 기능에 충실
    • 속도나 효율성에 크게 민감하지 않을 경우 사용하기 좋다.
  • yarn
    • 빠른 속도와 안정성을 원하는 사용자에게 적합
    • 특히 대규모 프로젝트나 모노레포에서 유용
  • pnpm
    • 성능과 디스크 공간 효율성을 중시하는 사용자에게 적합
    • 모노레포와 의존성 관리가 중요한 프로젝트에 유용

 

게시글에서는 npm은 작은 프로젝트, yarn은 중간, pnpm 대규모라고 설명하였다.

하지만 실제로 프로젝트 크기보다 팀 문화, CI/CD 환경, 호환성 요구도 중요하다.

어떤 패키지 매니저를 선택할지는 프로젝트규모, 팀 협업 환경, 빌드 도구와의 호환성, CI/CD환경도 고려하여 선택해야 한다.

항목 npm yarn pnpm
속도 보통 빠름 매우 빠름
디스크 매우 효율적
방식 복사 복사/PnP 하드링크

 

 


잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊

댓글과 좋아요는 큰 힘이 됩니다!

 

더보기

 

728x90
반응형
Comments