0deps 운동: 로컬 의존성 및 불변 계약
소프트웨어 개발자들은 종종 모든 프로젝트에 수백 개의 외부 라이브러리를 설치합니다. 현대적인 프레임워크는 수천 개의 전이적 의존성(transitive dependencies)에 의존합니다. 이는 여러분의 애플리케이션이 수백 명의 알 수 없는 기여자들의 코드를 실행한다는 것을 의미합니다.
이러한 속도는 소프트웨어 공급망에 막대한 위험을 초래합니다.
0deps 운동은 단순한 질문을 던집니다: 만약 여러분의 애플리케이션이 실제로 여러분이 제어하는 코드만 실행한다면 어떨까요?
모든 의존성은 공격 표면(attack surface)을 넓힙니다. 의존성은 보안 취약점을 유발하거나, 관리가 중단되거나, 새로운 업데이트로 인해 코드를 망가뜨릴 수 있습니다. 결과적으로 프로덕션 환경에서 실행되는 코드에 대한 제어권을 잃게 됩니다.
0deps 모델에서는 모든 의존성을 프로젝트 저장소로 직접 가져옵니다. 설치 중에 동적으로 다운로드하지 않습니다. 앱을 빌드하고 실행하는 데 필요한 모든 것이 이미 그곳에 있습니다.
이 접근 방식은 다음과 같은 여러 이점을 제공합니다:
- 재현 가능한 빌드 (Reproducible builds)
- 외부 패키지 레지스트리에 대한 의존성 감소
- 중앙 집중식 보안 감사
- 향상된 예측 가능성
- 낮은 공급망 위험
핵심 원칙은 코드의 변경을 막는 것이 아닙니다. 알고리즘과 보안 패치는 계속 진화해야 합니다. 변하지 않고 안정적으로 유지되는 것은 공개 계약(public contract)입니다.
각 라이브러리는 정교하게 설계된 인터페이스를 노출합니다.
- authenticate()
- createSession()
- verifyPasskey()
이 함수들은 계약을 정의합니다. 그 계약은 절대 변하지 않습니다. 내부 코드를 다시 작성하거나 라이브러리 전체를 교체할 수도 있습니다. 애플리케이션의 나머지 부분은 계약하고만 통신하기 때문에 그대로 유지됩니다.
취약점이 발견되면 내부적으로 수정합니다. 인터페이스 뒤에 있는 구현(implementation)을 업데이트합니다. 공개 API는 동일하게 유지됩니다. 여러분의 애플리케이션은 코드 변경 없이 계속 작동합니다.
이 구조는 외부 코드를 격리하기 위해 내부 어댑터(adapter)를 사용합니다: Application ↓ Public Interface ↓ Adapter ↓ Implementation
외부 라이브러리가 사라지더라도 어댑터만 업데이트하면 됩니다. 앱의 다른 부분은 망가지지 않습니다.
0deps 운동은 오픈 소스에 반대하는 것이 아닙니다. 오픈 소스를 사용하는 방식을 바꾸는 것입니다. 라이브러리는 여러분이 직접 감사하고 버전을 관리하는 통합 구성 요소가 됩니다.
이를 통해 수십 년 동안 지속되는 소프트웨어를 만들 수 있습니다. 구현은 변하지만 계약은 유지됩니다. 이러한 안정성은 소프트웨어를 예측 가능하고 탄력적으로 만듭니다.
