회사에서 쓰는 기술 스택이 있다. React, TypeScript, Next.js, Zustand, Tailwind CSS. 이 조합이 손에 완전히 익었다. 새 프로젝트가 시작돼도 초기 세팅을 30분 안에 끝낼 수 있고, 웬만한 UI 패턴은 머리보다 손이 먼저 움직인다. 리스트 렌더링, 폼 핸들링, 모달, 토스트, 무한 스크롤. 다 해봤고, 다 할 수 있다. 편하다.
근데 최근에 이 "편함"이 좀 무섭다.
익숙함의 함정
작년에 팀에서 Vue.js로 된 레거시 프로젝트를 유지보수할 사람이 필요했다. 사내 다른 팀에서 넘어온 프로젝트인데, Vue 2 기반에 Vuex를 쓰고 있었다. 아무도 자원 안 했다. 나도. React만 하고 싶었으니까. "Vue는 안 해봐서요"라는 말이 편한 핑계였다. 결국 외부 프리랜서를 데려왔는데, 그 사람은 React도 Vue도 Svelte도 했다. 프레임워크를 가리지 않았다. 첫 주에 코드베이스를 파악하고, 둘째 주부터 바로 피처를 찍어냈다.
그 사람이 점심 먹으면서 한 말이 머리에 남았다. "프레임워크는 결국 UI를 그리는 도구인데, 근본 원리는 비슷하니까요. 상태가 바뀌면 화면이 바뀐다는 거. React든 Vue든 Svelte든." 맞는 말이다. 근데 나는 그 "근본 원리"를 React라는 렌즈로만 이해하고 있었다. 다른 렌즈를 끼워본 적이 없으니까, 내가 보는 게 전체인 줄 알았다.
그 사람이 떠나고 나서 Vue 문서를 한번 열어봤다. template 문법이 낯설었다. JSX에 익숙한 눈에는 "이게 뭐지?" 싶었다. v-if, v-for, v-model. 30분 읽다가 닫았다. "지금 당장 필요 없으니까"라는 이유로. 합리적인 이유 같지만, 사실은 불편해서 도망친 거였다.
불편한 시도들
그래서 올해 초부터 일부러 불편한 걸 하려고 한다. 작게라도.
첫 번째로 Rust를 조금 건드려 봤다. 프론트엔드와 직접 관련은 없지만, WASM 쪽으로 연결될 수 있고, 요즘 빌드 도구들이 다 Rust 기반이라서. SWC, Turbopack, Biome, oxc. 프론트엔드 도구 생태계의 밑바닥이 Rust로 깔리고 있다. 직접 Rust로 뭔가 만들 일은 없겠지만, 이 도구들이 어떤 원리로 동작하는지 감이라도 잡고 싶었다.
Rust 공식 튜토리얼을 시작했다. 소유권(ownership) 개념에서 막혔다. JavaScript에서는 생각해본 적 없는 개념이다. 변수를 다른 변수에 할당하면 원래 변수를 못 쓴다? 메모리를 직접 관리해야 한다? 3일 만에 덮었다. 아직 이른가 싶었다. 근데 그 3일 동안 "가비지 컬렉션이 없는 세계"를 잠깐이나마 본 건 의미가 있었다. JavaScript가 얼마나 편한 언어인지 체감했다.
두 번째로 백엔드를 좀 해봤다. Express로 간단한 REST API를 만들어봤다. 라우팅, 미들웨어, 데이터베이스 연결. 생각보다 재미있었다. 프론트에서 API를 "쓰는" 입장에서만 보다가, "만드는" 입장으로 가니까 시야가 달라졌다. 왜 백엔드 개발자가 특정 형태로 응답을 주는지 이해가 됐다. 페이지네이션을 offset 기반으로 할지 cursor 기반으로 할지, 에러 응답 형식을 어떻게 통일할지, 인증 미들웨어를 어디에 둘지. 이전에는 "왜 이렇게 주는 거야" 하고 불만만 가졌는데, 직접 만들어보니 "아 이럴 수밖에 없구나" 하는 경우가 많았다.
세 번째로 디자인 시스템을 공부하기 시작했다. Figma를 열어서 디자이너가 어떻게 컴포넌트를 구성하는지 봤다. 오토 레이아웃이라는 개념이 CSS Flexbox랑 거의 같다는 걸 처음 알았다. 디자이너와 대화할 때 "여기 패딩 좀 주세요" 대신 "이 오토 레이아웃의 gap을 12에서 16으로 해볼까요?" 같은 말을 쓸 수 있게 됐다. 디자이너가 놀란 눈으로 봤다. "개발자가 오토 레이아웃을 안다고?" 이 작은 공통 언어가 협업을 꽤 편하게 만들었다.
불편함의 비용
불편한 걸 하면 당연히 느려진다. Rust 튜토리얼 하는 시간에 React 고급 패턴을 공부했으면 회사 일에 바로 도움이 됐을 거다. Express API 만드는 시간에 Next.js Server Action을 깊게 팠으면 프로젝트에 바로 적용할 수 있었을 거다. Figma 공부하는 시간에 CSS 애니메이션을 연습했으면 더 화려한 UI를 만들 수 있었을 거다.
이 기회비용 때문에 망설여진다. 지금 당장 써먹을 수 있는 걸 깊게 할 것인가, 당장은 안 써먹지만 폭을 넓힐 것인가. 정답은 없는 것 같다. 사람마다 상황이 다르고, 시기마다 필요한 게 다르니까.
팀 리드한테 이 고민을 말했더니, "둘 다 해"라고 했다. 평일에는 깊게, 주말에는 넓게. 근데 주말에 코딩하고 싶지 않은 마음도 있어서, 현실적으로는 평일 퇴근 후 30분-1시간 정도를 "불편한 공부" 시간으로 쓰고 있다. 솔직히 안 하는 날이 더 많다. 3일에 한 번 정도? 피곤하면 넷플릭스가 이긴다.
시장은 기다려주지 않는다
작년에 AI 코딩 도구가 본격적으로 퍼지기 시작했다. 처음에는 "이걸로 코딩하다니 장난감 아닌가" 했는데, 옆에서 시니어가 Copilot으로 보일러플레이트를 뚝딱 만드는 걸 보고 생각이 바뀌었다. 반복적인 코드 작성 시간이 확 줄었다. 타입 정의, 테스트 케이스, API 연동 코드 같은 것들. 그 시간에 설계나 리뷰에 더 집중할 수 있었다.
AI 도구를 안 쓰면 뒤처지는 게 아니라, 불필요하게 시간을 쓰는 거다. 이것도 컴포트존이었다. "나는 직접 코드를 쳐야 해"라는 고집. "자동 완성에 의존하면 실력이 안 늘어"라는 믿음. 결국 AI 도구를 쓰기 시작했고, 지금은 없으면 답답하다. 이전의 나를 설득하는 데 한 달이 걸렸다.
프론트엔드 시장 자체도 변하고 있다. 서버 컴포넌트, 엣지 컴퓨팅, 마이크로 프론트엔드, Islands Architecture. 2년 전 부트캠프에서 배운 내용만으로는 따라가기 어려운 방향으로 가고 있다. CRA(Create React App)로 SPA 만들던 시절이 불과 2-3년 전인데, 지금은 완전히 다른 세계다. "나는 React 잘 해"만으로는 3년 후에 어떻게 될지 모르겠다.
불편함을 버티는 법
사실 특별한 방법은 없다. 그냥 불편한 걸 시작하고, 잘 안 되면 좀 답답하고, 그래도 조금씩 하다 보면 어느 순간 불편하지 않게 된다. 그러면 또 새로운 불편함을 찾는다. 이 사이클의 반복.
TypeScript를 처음 배울 때가 생각난다. JavaScript가 편한데 왜 타입을 일일이 써야 하냐고 투덜거렸다. any를 남발했다. 인터페이스 정의하는 게 코드만 길어지는 것 같아서 짜증났다. 지금? any 쓰면 코드 리뷰에서 스스로도 불편하다. strict mode 없이는 코드를 쓸 수 없다. 익숙해진 거다. 그 불편했던 시간이 지금의 편안함을 만들었다.
불편함은 성장의 신호라는 말이 있는데, 경험적으로 맞는 것 같다. 편하다는 건 새로운 걸 안 하고 있다는 뜻이고, 불편하다는 건 뭔가 확장하고 있다는 뜻이다. 다만 모든 불편함이 좋은 불편함은 아니다. 의미 없는 삽질은 그냥 삽질이다. 어떤 불편함이 성장으로 이어지고 어떤 불편함이 시간 낭비인지, 그걸 구별하는 감각은 아직 없다. 이것도 경험으로 쌓이는 건지, 아니면 영원히 모르는 건지.
한 가지 확실한 건, 편한 상태에서는 아무것도 안 바뀐다는 거다. React만 할 줄 알던 나는 1년 전이나 지금이나 React만 할 줄 안다. 근데 Express를 만져본 나는, 프론트에서 API를 설계할 때 백엔드 사정을 고려할 수 있게 됐다. Figma를 열어본 나는, 디자이너와 같은 언어로 이야기할 수 있게 됐다. 작은 불편함이 작은 변화를 만들었다. 그 작은 변화가 쌓여서 뭐가 될지는 아직 모르겠지만, 적어도 가만히 있는 것보다는 나을 거라고 생각한다.
요즘은 Vue 문서를 다시 열어볼까 생각 중이다. 작년에 30분 보고 닫았던 그 문서. 이번에는 좀 더 버텨볼 수 있을 것 같다. template 문법이 낯설어도, JSX와 다른 관점에서 UI를 생각하는 경험 자체가 의미 있을 거라고 본다.
