[{"data":1,"prerenderedAt":259},["ShallowReactive",2],{"$ffU1BQOLOnh3uOgKNbshBr5iUkYwT7LuOkK3ur7ncAaI":3,"mdc-co2mr7-key":19},{"post_id":4,"title":5,"description":6,"published_at":7,"tags":8,"content":17,"status":18},"69aee1e3-4a62-40ec-b004-cf9f376a5439","CSS-in-JS의 몰락","styled-components와 Emotion의 현재","2025-10-11",[9,12,14,16],{"tag":10,"category":11},"styled-components","dev",{"tag":13,"category":11},"Emotion",{"tag":15,"category":11},"CSS-in-JS",{"tag":11,"category":11},"새로운 프로젝트를 시작하면서 스타일링 라이브러리를 선택하려던 찰나, styled-components가 maintenance mode에 진입했다는 소식을 접했다. React 생태계에서 가장 인기 있던 CSS-in-JS 솔루션 중 하나가 사실상 개발 중단된 것이다. 이게 단순히 한 라이브러리의 문제가 아니라 CSS-in-JS 생태계 전반의 변화를 보여주는 신호탄 같아서, 현재 상황을 정리해봤다.\n\n## styled-components의 종말\n\n2025년 3월 17일, styled-components는 공식적으로 maintenance mode에 진입했다. 새로운 기능 개발은 없고, 심각한 버그 수정과 보안 패치만 제공된다. 창시자인 Max Stoiber는 X(구 트위터)에서 감회에 찬 글을 남겼다. 12억 건의 npm 다운로드, 40,000개의 GitHub 스타를 기록한 라이브러리의 마지막이었다.\n\n왜 이런 결정을 내렸을까? 세 가지 핵심 이유가 있다.\n\n**React의 진화**: React가 Server Components 방향으로 나아가면서 기존 Context API와의 호환성 문제가 발생했다. styled-components는 여기에 적응할 upgrade path가 없었다.\n\n**생태계의 변화**: CSS-in-JS 자체가 생태계에서 인기를 잃고 있다. Tailwind CSS, CSS Modules 같은 대안들이 더 나은 성능과 개발 경험을 제공하기 시작했다.\n\n**메인테이너의 이탈**: 마지막 메인테이너였던 Evan Jacobs가 실제 프로덕션에서 styled-components를 더 이상 사용하지 않았다. 본인이 쓰지 않는 라이브러리를 무료로 유지보수하는 건 지속 가능하지 않다.\n\n## Emotion은 다르다... 아직은\n\nstyled-components의 소식을 듣고 자연스럽게 다음 질문이 생긴다. Emotion은 어떨까?\n\n다행히도 Emotion은 아직 maintenance mode가 아니다. GitHub discussion에서 메인테이너 Andarist가 \"Emotion is here to stay\"라고 명확히 밝혔다. 2024-2025년에도 소스코드를 TypeScript로 마이그레이션하고, CSS @container, cascade @layers 같은 최신 기능 지원을 추가했다. 표면적으로는 여전히 활발하다.\n\n하지만 조심스러운 신호들이 있다. Emotion의 메인테이너 중 한 명인 Sam Magura는 2022년에 자신의 회사 Spot에서 runtime CSS-in-JS를 Sass로 교체했다고 밝혔다. 렌더링 시간이 거의 2배 차이 났고(27.7ms vs 54ms), 번들 사이즈와 서버 렌더링 문제도 있었다고 한다.\n\n더 중요한 건, React 팀이 CSS-in-JS를 \"권장하지 않는다\"는 점에 대해 Andarist는 \"불가능해질 가능성은 낮다\"며 낙관적이지만, static extraction 같은 근본적인 변화는 계획하지 않는다고 했다. 즉, 현재 방향을 유지하되 React 생태계의 흐름과는 점점 멀어질 수 있다는 의미다.\n\n## 단기 해결책: 성능 개선 포크\n\n당장 대규모 코드베이스를 migration 하기 어렵다면? Sanity 팀이 공개한 styled-components 포크가 있다. Linear에서 테스트했을 때 초기 렌더링이 최대 40% 빨라졌다고 한다.\n\n이들은 원래 PR을 upstream에 보냈지만 메인테이너가 1명이고 무료로 34,000개 스타 프로젝트를 관리하는 상황에서 merge가 되지 않았다. 결국 포크로 공개했다. migration 계획을 세우는 동안 성능이라도 개선하고 싶다면 고려해볼 만하다.\n\n## 어디로 가야 할까?\n\n**새 프로젝트를 시작한다면**, styled-components는 절대 선택지가 아니다. 메인테이너 본인도 권장하지 않는다.\n\n**기존 프로젝트라면**, 상황에 따라 다르다:\n\n- **급한 migration이 필요 없는 경우**: 당장은 괜찮다. 하지만 계획은 세워야 한다.\n- **성능이 중요한 경우**: 위의 포크를 고려하거나, 점진적 migration을 시작한다.\n- **장기적 안정성이 중요한 경우**: 지금부터 migration 계획을 수립한다.\n\n대안들은 명확하다:\n\n**Linaria**: styled-components와 가장 유사한 DX. 전환이 가장 쉽다. zero-runtime이라 성능도 좋다.\n\n**CSS Modules**: 가장 안정적이고 프레임워크에 독립적. 장기적으로 가장 안전한 선택.\n\n**Tailwind CSS**: 유틸리티 우선 방식. 학습 곡선이 있지만 생산성이 높다.\n\n**Vanilla Extract**: 제로 런타임에 타입 안전성까지. TypeScript 사용자에게 좋다.\n\n## 배운 점\n\n이번 일을 통해 몇 가지를 깨달았다.\n\n첫째, 인기 있는 오픈소스도 영원하지 않다. styled-components는 12억 다운로드를 기록했지만 결국 maintenance mode에 들어갔다. 기술 선택은 현재의 인기가 아니라 지속 가능성을 봐야 한다.\n\n둘째, 생태계의 방향성을 읽어야 한다. React 팀이 CSS-in-JS를 권장하지 않는다는 건 중요한 신호다. 프레임워크가 가는 방향과 반대로 가면 언젠가 문제가 생긴다.\n\n셋째, 메인테이너의 동기가 중요하다. Evan Jacobs가 본인 프로젝트에서 styled-components를 쓰지 않는다는 건, 그 라이브러리의 미래에 대한 가장 정직한 신호였다.\n\n결국 CSS-in-JS는 특정 시기의 특정 문제를 해결하기 위한 훌륭한 솔루션이었다. 하지만 웹 표준이 발전하고, 빌드 타임 솔루션이 성숙해지면서 런타임 오버헤드를 감수할 이유가 줄어들었다. 변화를 받아들이고 다음 단계로 나아갈 때다.","published",{"data":20,"body":21},{},{"type":22,"children":23},"root",[24,32,39,44,49,60,70,80,86,91,96,101,106,112,117,122,128,138,148,183,188,198,208,218,228,234,239,244,249,254],{"type":25,"tag":26,"props":27,"children":28},"element","p",{},[29],{"type":30,"value":31},"text","새로운 프로젝트를 시작하면서 스타일링 라이브러리를 선택하려던 찰나, styled-components가 maintenance mode에 진입했다는 소식을 접했다. React 생태계에서 가장 인기 있던 CSS-in-JS 솔루션 중 하나가 사실상 개발 중단된 것이다. 이게 단순히 한 라이브러리의 문제가 아니라 CSS-in-JS 생태계 전반의 변화를 보여주는 신호탄 같아서, 현재 상황을 정리해봤다.",{"type":25,"tag":33,"props":34,"children":36},"h2",{"id":35},"styled-components의-종말",[37],{"type":30,"value":38},"styled-components의 종말",{"type":25,"tag":26,"props":40,"children":41},{},[42],{"type":30,"value":43},"2025년 3월 17일, styled-components는 공식적으로 maintenance mode에 진입했다. 새로운 기능 개발은 없고, 심각한 버그 수정과 보안 패치만 제공된다. 창시자인 Max Stoiber는 X(구 트위터)에서 감회에 찬 글을 남겼다. 12억 건의 npm 다운로드, 40,000개의 GitHub 스타를 기록한 라이브러리의 마지막이었다.",{"type":25,"tag":26,"props":45,"children":46},{},[47],{"type":30,"value":48},"왜 이런 결정을 내렸을까? 세 가지 핵심 이유가 있다.",{"type":25,"tag":26,"props":50,"children":51},{},[52,58],{"type":25,"tag":53,"props":54,"children":55},"strong",{},[56],{"type":30,"value":57},"React의 진화",{"type":30,"value":59},": React가 Server Components 방향으로 나아가면서 기존 Context API와의 호환성 문제가 발생했다. styled-components는 여기에 적응할 upgrade path가 없었다.",{"type":25,"tag":26,"props":61,"children":62},{},[63,68],{"type":25,"tag":53,"props":64,"children":65},{},[66],{"type":30,"value":67},"생태계의 변화",{"type":30,"value":69},": CSS-in-JS 자체가 생태계에서 인기를 잃고 있다. Tailwind CSS, CSS Modules 같은 대안들이 더 나은 성능과 개발 경험을 제공하기 시작했다.",{"type":25,"tag":26,"props":71,"children":72},{},[73,78],{"type":25,"tag":53,"props":74,"children":75},{},[76],{"type":30,"value":77},"메인테이너의 이탈",{"type":30,"value":79},": 마지막 메인테이너였던 Evan Jacobs가 실제 프로덕션에서 styled-components를 더 이상 사용하지 않았다. 본인이 쓰지 않는 라이브러리를 무료로 유지보수하는 건 지속 가능하지 않다.",{"type":25,"tag":33,"props":81,"children":83},{"id":82},"emotion은-다르다-아직은",[84],{"type":30,"value":85},"Emotion은 다르다... 아직은",{"type":25,"tag":26,"props":87,"children":88},{},[89],{"type":30,"value":90},"styled-components의 소식을 듣고 자연스럽게 다음 질문이 생긴다. Emotion은 어떨까?",{"type":25,"tag":26,"props":92,"children":93},{},[94],{"type":30,"value":95},"다행히도 Emotion은 아직 maintenance mode가 아니다. GitHub discussion에서 메인테이너 Andarist가 \"Emotion is here to stay\"라고 명확히 밝혔다. 2024-2025년에도 소스코드를 TypeScript로 마이그레이션하고, CSS @container, cascade @layers 같은 최신 기능 지원을 추가했다. 표면적으로는 여전히 활발하다.",{"type":25,"tag":26,"props":97,"children":98},{},[99],{"type":30,"value":100},"하지만 조심스러운 신호들이 있다. Emotion의 메인테이너 중 한 명인 Sam Magura는 2022년에 자신의 회사 Spot에서 runtime CSS-in-JS를 Sass로 교체했다고 밝혔다. 렌더링 시간이 거의 2배 차이 났고(27.7ms vs 54ms), 번들 사이즈와 서버 렌더링 문제도 있었다고 한다.",{"type":25,"tag":26,"props":102,"children":103},{},[104],{"type":30,"value":105},"더 중요한 건, React 팀이 CSS-in-JS를 \"권장하지 않는다\"는 점에 대해 Andarist는 \"불가능해질 가능성은 낮다\"며 낙관적이지만, static extraction 같은 근본적인 변화는 계획하지 않는다고 했다. 즉, 현재 방향을 유지하되 React 생태계의 흐름과는 점점 멀어질 수 있다는 의미다.",{"type":25,"tag":33,"props":107,"children":109},{"id":108},"단기-해결책-성능-개선-포크",[110],{"type":30,"value":111},"단기 해결책: 성능 개선 포크",{"type":25,"tag":26,"props":113,"children":114},{},[115],{"type":30,"value":116},"당장 대규모 코드베이스를 migration 하기 어렵다면? Sanity 팀이 공개한 styled-components 포크가 있다. Linear에서 테스트했을 때 초기 렌더링이 최대 40% 빨라졌다고 한다.",{"type":25,"tag":26,"props":118,"children":119},{},[120],{"type":30,"value":121},"이들은 원래 PR을 upstream에 보냈지만 메인테이너가 1명이고 무료로 34,000개 스타 프로젝트를 관리하는 상황에서 merge가 되지 않았다. 결국 포크로 공개했다. migration 계획을 세우는 동안 성능이라도 개선하고 싶다면 고려해볼 만하다.",{"type":25,"tag":33,"props":123,"children":125},{"id":124},"어디로-가야-할까",[126],{"type":30,"value":127},"어디로 가야 할까?",{"type":25,"tag":26,"props":129,"children":130},{},[131,136],{"type":25,"tag":53,"props":132,"children":133},{},[134],{"type":30,"value":135},"새 프로젝트를 시작한다면",{"type":30,"value":137},", styled-components는 절대 선택지가 아니다. 메인테이너 본인도 권장하지 않는다.",{"type":25,"tag":26,"props":139,"children":140},{},[141,146],{"type":25,"tag":53,"props":142,"children":143},{},[144],{"type":30,"value":145},"기존 프로젝트라면",{"type":30,"value":147},", 상황에 따라 다르다:",{"type":25,"tag":149,"props":150,"children":151},"ul",{},[152,163,173],{"type":25,"tag":153,"props":154,"children":155},"li",{},[156,161],{"type":25,"tag":53,"props":157,"children":158},{},[159],{"type":30,"value":160},"급한 migration이 필요 없는 경우",{"type":30,"value":162},": 당장은 괜찮다. 하지만 계획은 세워야 한다.",{"type":25,"tag":153,"props":164,"children":165},{},[166,171],{"type":25,"tag":53,"props":167,"children":168},{},[169],{"type":30,"value":170},"성능이 중요한 경우",{"type":30,"value":172},": 위의 포크를 고려하거나, 점진적 migration을 시작한다.",{"type":25,"tag":153,"props":174,"children":175},{},[176,181],{"type":25,"tag":53,"props":177,"children":178},{},[179],{"type":30,"value":180},"장기적 안정성이 중요한 경우",{"type":30,"value":182},": 지금부터 migration 계획을 수립한다.",{"type":25,"tag":26,"props":184,"children":185},{},[186],{"type":30,"value":187},"대안들은 명확하다:",{"type":25,"tag":26,"props":189,"children":190},{},[191,196],{"type":25,"tag":53,"props":192,"children":193},{},[194],{"type":30,"value":195},"Linaria",{"type":30,"value":197},": styled-components와 가장 유사한 DX. 전환이 가장 쉽다. zero-runtime이라 성능도 좋다.",{"type":25,"tag":26,"props":199,"children":200},{},[201,206],{"type":25,"tag":53,"props":202,"children":203},{},[204],{"type":30,"value":205},"CSS Modules",{"type":30,"value":207},": 가장 안정적이고 프레임워크에 독립적. 장기적으로 가장 안전한 선택.",{"type":25,"tag":26,"props":209,"children":210},{},[211,216],{"type":25,"tag":53,"props":212,"children":213},{},[214],{"type":30,"value":215},"Tailwind CSS",{"type":30,"value":217},": 유틸리티 우선 방식. 학습 곡선이 있지만 생산성이 높다.",{"type":25,"tag":26,"props":219,"children":220},{},[221,226],{"type":25,"tag":53,"props":222,"children":223},{},[224],{"type":30,"value":225},"Vanilla Extract",{"type":30,"value":227},": 제로 런타임에 타입 안전성까지. TypeScript 사용자에게 좋다.",{"type":25,"tag":33,"props":229,"children":231},{"id":230},"배운-점",[232],{"type":30,"value":233},"배운 점",{"type":25,"tag":26,"props":235,"children":236},{},[237],{"type":30,"value":238},"이번 일을 통해 몇 가지를 깨달았다.",{"type":25,"tag":26,"props":240,"children":241},{},[242],{"type":30,"value":243},"첫째, 인기 있는 오픈소스도 영원하지 않다. styled-components는 12억 다운로드를 기록했지만 결국 maintenance mode에 들어갔다. 기술 선택은 현재의 인기가 아니라 지속 가능성을 봐야 한다.",{"type":25,"tag":26,"props":245,"children":246},{},[247],{"type":30,"value":248},"둘째, 생태계의 방향성을 읽어야 한다. React 팀이 CSS-in-JS를 권장하지 않는다는 건 중요한 신호다. 프레임워크가 가는 방향과 반대로 가면 언젠가 문제가 생긴다.",{"type":25,"tag":26,"props":250,"children":251},{},[252],{"type":30,"value":253},"셋째, 메인테이너의 동기가 중요하다. Evan Jacobs가 본인 프로젝트에서 styled-components를 쓰지 않는다는 건, 그 라이브러리의 미래에 대한 가장 정직한 신호였다.",{"type":25,"tag":26,"props":255,"children":256},{},[257],{"type":30,"value":258},"결국 CSS-in-JS는 특정 시기의 특정 문제를 해결하기 위한 훌륭한 솔루션이었다. 하지만 웹 표준이 발전하고, 빌드 타임 솔루션이 성숙해지면서 런타임 오버헤드를 감수할 이유가 줄어들었다. 변화를 받아들이고 다음 단계로 나아갈 때다.",1777192769744]