0deps 운동: 로컬 의존성 및 불변 계약
소프트웨어 개발자들은 종종 모든 프로젝트에 수백 개의 외부 라이브러리를 설치합니다. 현대적인 프레임워크는 수천 개의 전이적 의존성(transitive dependencies)에 의존합니다. 이는 여러분의 애플리케이션이 수백 명의 알 수 없는 기여자들의 코드를 실행한다는 것을 의미합니다.
이러한 설정은 개발 속도를 높여주지만, 소프트웨어 공급망(software supply chain)에 막대한 보안 리스크를 초래하기도 합니다.
0deps 운동은 간단한 질문을 던집니다: 만약 여러분의 애플리케이션이 실제로 여러분이 제어하는 코드만 실행한다면 어떨까요?
모든 의존성은 공격 표면(attack surface)을 넓힙니다. 의존성은 다음과 같은 문제를 일으킬 수 있습니다:
- 보안 결함을 유발할 수 있습니다.
- 공급망 공격의 대상이 될 수 있습니다.
- 관리되지 않고 방치될 수 있습니다.
- 공개 API를 변경할 수 있습니다.
- 하위 호환성을 깨뜨릴 수 있습니다.
0deps 모델에서는 필요한 모든 의존성을 프로젝트 저장소에 직접 포함합니다. 설치 중에 동적으로 다운로드하지 않습니다. 앱을 빌드하고 실행하는 데 필요한 모든 것이 첫 번째 클론(clone) 시점부터 이미 존재합니다.
이 접근 방식은 다음과 같은 이점을 제공합니다:
- 재현 가능한 빌드(Reproducible builds).
- 외부 패키지 레지스트리에 대한 의존성 감소.
- 중앙 집중식 보안 감사.
- 높은 예측 가능성.
- 축소된 공급망 공격 표면.
0deps가 코드 업데이트를 중단한다는 의미는 아닙니다. 알고리즘과 보안 패치는 계속 진화해야 합니다. 대신, 공개 계약(public contract)을 안정적으로 유지하는 것입니다.
각 라이브러리는 세심하게 설계된 인터페이스를 노출합니다. 예를 들어:
- authenticate()
- createSession()
- verifyPasskey()
이 함수들은 계약을 정의합니다. 이 계약은 변하지 않습니다. 애플리케이션의 나머지 부분에 영향을 주지 않고도 내부 코드를 다시 작성하거나 내부 라이브러리를 교체할 수 있습니다.
취약점이 발견되면 인터페이스 뒤의 구현(implementation)을 업데이트합니다. 공개 API는 동일하게 유지됩니다. 애플리케이션은 코드 변경 없이 계속 작동합니다.
구조는 다음과 같습니다: 애플리케이션 ↓ 공개 인터페이스 ↓ 내부 어댑터 ↓ 구현
외부 라이브러리가 사라지더라도 어댑터만 변경하면 됩니다. 애플리케이션의 다른 부분은 깨지지 않습니다. 이러한 격리는 악성 패키지, 레지스트리 침해, 의존성 혼란(dependency confusion)으로부터 여러분을 보호합니다.
프로젝트는 수십 년 동안 지속되지만, 라이브러리와 프레임워크는 그렇지 않습니다. 0deps를 사용하면 주변 생태계가 변하더라도 애플리케이션이 수년 동안 동일하고 안정적인 계약을 사용할 수 있습니다.
이를 통해 예측 가능하고 탄력적이며 유지보수가 용이한 소프트웨어를 얻을 수 있습니다.
Optional learning community: https://t.me/GyaanSetuAi
