거대 스토어의 딜레마

2

발행일: 2025년 05월 16일

Zustand 왕국은 번성했지만, 그 수도(首都)는 점점 더 복잡하고 비대해지고 있었다. 다이시 카토는 최근 컨설팅을 의뢰받은 한 거대 핀테크 프로젝트의 코드베이스를 살펴보며 이 사실을 다시 한번 뼈저리게 느끼고 있었다.

수백 명의 개발자가 참여하고, 수십 개의 독립적인 팀이 각자의 모듈을 개발하는 괴물 같은 프로젝트. 그들은 전사적으로 Zustand를 도입하여 상태 관리를 일원화했지만, 그 결과는 카토의 예상과는 조금 다른 방향으로 흘러가고 있었다.

“이게… Zustand 스토어 파일 하나라고?”

카토는 눈을 의심했다. 그의 모니터 화면을 가득 채운 것은 수천 라인에 달하는 거대한 자바스크립트 파일이었다. 그 안에는 사용자 인증 상태부터 시작해서, 계좌 정보, 투자 포트폴리오, 실시간 차트 데이터, 온갖 종류의 설정값과 임시 상태까지, 프로젝트의 모든 상태 조각들이 거대한 하나의 객체 안에 뒤섞여 있었다. 마치 온갖 종류의 물건들이 뒤죽박죽 쌓여 있는 초대형 창고와 같았다.

각 팀은 자신들이 맡은 기능에 필요한 상태 조각(slice)들을 이 중앙 스토어에 추가했다. 처음에는 깔끔하게 분리된 것처럼 보였지만, 프로젝트 규모가 커지고 기능 간의 의존성이 복잡해지면서 스토어 내부는 점점 더 혼돈에 빠져들었다.

“계좌 이체 모듈에서 쓰는 상태가 왜 결제 내역 조회 모듈 옆에 정의되어 있는 거지?”

카토는 미간을 찌푸렸다. 특정 기능을 개발하는 개발자는 자신이 필요한 상태 로직을 수정하거나 이해하기 위해, 자신의 작업 맥락과는 전혀 상관없는 수많은 다른 상태 정의들을 헤치고 나아가야 했다. 마치 도서관에서 특정 분야의 책을 찾기 위해, 전혀 다른 분야의 서가들을 끝없이 지나쳐야 하는 기분이었다.

상태를 정의하는 곳과 실제로 사용하는 곳 사이의 거리. 그것이 문제였다. Zustand는 분명 셀렉터를 통해 사용하는 쪽에서는 필요한 것만 가져올 수 있게 해주었지만, 상태를 정의하고 관리하는 측면에서는 모든 것이 중앙에 집중되면서 응집성(Cohesion)이 떨어지고 있었다.

더 심각한 문제는 코드 스플리팅(Code Splitting)과의 잠재적인 충돌이었다. 이 프로젝트는 사용자가 방문하는 페이지나 사용하는 기능에 따라 필요한 코드만 동적으로 불러오는 코드 스플리팅을 적극적으로 활용하고 있었다. 이론적으로는 초기 로딩 속도를 획기적으로 개선할 수 있는 좋은 전략이었다.

하지만 이 거대한 Zustand 스토어 파일은 그 노력에 찬물을 끼얹을 수 있었다. 사용자가 단순히 로그인 페이지만 방문했을 뿐인데도, 투자 포트폴리오 관리나 실시간 차트 표시에 필요한 상태 로직까지 포함된 거대한 스토어 파일 전체가 초기 번들에 포함될 위험이 있었다. Zustand 자체는 가볍지만, 그 안에 담기는 ‘내용물’이 너무 비대해져 버린 것이다.

“이건… Zustand의 잘못이라기보다는, 거대 스토어 모델 자체의 태생적 한계일지도 몰라.”

카토는 깊은 한숨을 내쉬었다. Zustand는 분명 많은 문제를 해결했지만, 애플리케이션의 규모와 복잡성이 특정 임계점을 넘어서자 새로운 종류의 문제, 즉 ‘관리’와 ‘최적화’의 어려움이라는 또 다른 벽에 부딪히고 있었다.

‘하나의 큰 창고’라는 모델이 과연 최선일까? 혹시… 상태들이 처음부터 자신이 있어야 할 곳, 즉 그것을 필요로 하는 컴포넌트나 모듈 가까이에 독립적으로 존재할 수는 없을까? 마치 각자의 집을 가진 주민들처럼.

그의 머릿속에서 어렴풋한 대안의 그림자가 흔들렸다. 아직은 형체를 알 수 없었지만, 그것은 분명 Zustand와는 다른 길을 가리키고 있었다.

“상태를 정의하는 곳과 사용하는 곳이… 너무 멀리 떨어져 있군.”

카토는 혼잣말처럼 중얼거렸다. 안정된 왕국의 화려함 뒤편에서, 그는 새로운 균열의 조짐을 발견하고 있었다. 그리고 그 균열은 더 근본적인 질문으로 이어지고 있었다. 상태 관리의 이상적인 모습은 과연 무엇인가? 그의 탐구는 이제 막 새로운 국면으로 접어들고 있었다.