떠나간 이가 있다면 찾아온 이도 생기죠 (떠나간 이 편)
한 프레임워크의 흥망성쇠를 함께한 분들을 보며 저도 언젠가 목도하는 날이 오지 않을까 생각했습니다. 이런 저에게 Recoil의 쇠퇴는 나름 의미있는 한 순간으로 남아있습니다.
그리고 최근 StyledComponents의 지원 중단과 tailwind v4가 저에게는 마치 떠나간 이가 있다면 찾아온 이도 생긴 인상이었습니다. 그래서 이 내용을 글로 담아보려고 합니다.
1.
StyledComponents는 저와의 관계는 마치 토이스토리의 우디와 앤디 같다고 말할 수 있습니다. 앤디라는 소년에게 우디는 본인의 애착이 담긴 인형이지만 성장함에 따라 잊혀진 존재가 되었습니다.
제가 StyledComponents를 사용하게 된 것 역시 우연으로 시작되었습니다. 개발을 막 시작했을 때 리액트를 쓰면 StyledComponents도 같이 써보라는 권유에 영문도 모른채 일단 쓰기 시작했습니다. 익숙해지자 토이프로젝트를 할 때마다 항상 제 CSS 프레임워크는 StyledComponents가 차지했습니다. 하지만 이유를 가지고 시작된 인연이 아니였어서 그런지 점점 StyledComponents와는 멀어졌습니다.
import styled from 'styled-components';
const Button = styled.button`
background: blue;
color: white;
padding: 10px;
`;
function App() {
return <Button>안녕 StyledComponents</Button>;
}
첫 번째 이유로는 태그와 스타일 태그의 구분의 모호함 때문이었습니다. StyledComponents는 스타일 태그를 사용하기에 저는 일반 태그와 스타일 태그를 구분하는데 불편함을 느꼈습니다. 이를 해소하고자 주변의 사용 사례를 참고하여 스타일 태그일 경우 앞에 S로 시작하게 하는 식으로 새로운 방법을 시도하기도 했습니다.
import styled from 'styled-components';
const SButton = styled.button`
background: blue;
color: white;
padding: 10px;
`;
function App() {
return <SButton>안녕 StyledComponents</SButton>;
}
2.
하지만 이런 사소한 불편함을 시작으로 다른 CSS 프레임워크에도 눈길을 돌리게 되었던 것 같습니다. 익숙했던 CSS in JS 방식의 Emotion을 사용하게 되었습니다. styled로 StyledComponents와 유사한 방식을 선택하거나 아니면 css로 CSS 방식을 선택할 수도 있습니다. 저는 스타일 태그를 만들 필요가 없다는 이유 때문에 Emotion의 css 방식을 자주 사용했던 것 같습니다.
import { css } from '@emotion/react';
function App() {
return (
<button
css={css`
background: blue;
color: white;
padding: 10px;
`}
>
안녕 StyledComponents
</button>
);
}
3.
Next.js가 유행하기 시작하면서 새로운 바람이 불게 되었습니다. 분명 CSS in JS는 신선한 존재였습니다. 스코프를 격리해준다는 이점도 있기는 하지만, 저에게 가장 의미있었던 것은 동적 스타일링이었습니다.
동적 스타일링이 가능했던 이유에 대해 더 깊게 살펴보면 다음과 같습니다. CSS in JS에서는 동적 스타일링이 가능한 이유는 JavaScript의 실행 시점과 관련이 있습니다. 전통적인 CSS는 정적 파일로, 브라우저가 HTML과 함께 로드할 때 한 번 파싱되어 적용됩니다. 이후 변경하려면 클래스를 추가/제거하거나 인라인 스타일을 조작해야 합니다. 반면 CSS in JS는 브라우저의 JavaScript 런타임에서 동작합니다. 따라서 브라우저 렌더링 과정에서 JavaScript가 실행될 때 1) 컴포넌트가 마운트되거나 업데이트될 때마다 JavaScript 코드가 평가하고 2) 이 시점에 props, state, 조건문 등을 기반으로 동적으로 스타일을 생성합니다. 3) 생성된 스타일은 CSS-in-JS 라이브러리에 의해 DOM에 스타일 태그로 삽입되거나 기존 스타일을 업데이트하기에 동적으로 스타일링이 가능해지는 것입니다.
const Button = styled.button`
background: ${props => props.isActive ? 'blue' : 'gray'};
opacity: ${props => props.disabled ? 0.5 : 1};
font-size: ${props => props.size === 'large' ? '18px' : '14px'};
`;
분명 화면을 다채롭게 해주는 CSS이지만 이벤트에 따라 동적으로 변화하는데에는 한계가 있었고, CSS in JS 덕분에 이런 한계를 극복하였다는 인상이었습니다.
4.
하지만 앞서 언급한 것처럼 어느 순간 모두에게 각광받던 CSS in JS가 외면받기 시작했습니다. 다양한 이유가 존재하겠지만 저에게는 크게 두 가지 이유가 와닿았습니다.
SSR 환경에서 CSS in JS는 JavaScript가 실행될 때 스타일을 생성하므로, 서버에서 HTML을 생성할 때 스타일 추출 과정이 추가로 필요합니다. 이는 SSR의 이점을 해친다고 보았습니다. 또한 CSS in JS 라이브러리는 자바스크립트 번들 크기를 증가시켜 초기 로딩 시간에 악영향을 준다는 점 역시 한 몫을 하였습니다. 이런 이유들이 모여 저는 자연스럽게 최근에는 tailwind를 애용하게 된 것 같습니다.
5.
최근 StyledComponents 팀에서 올린 공식 글을 보면서 CSS in JS의 현 주소를 더욱 실감하게 되었습니다.
The ecosystem in general has largely moved on from css-in-js as a concept while other technologies like tailwind have absolutely exploded in popularity.
생태계 전반적으로 CSS in JS라는 개념에서 벗어나는 추세이며, tailwind와 같은 다른 기술들이 폭발적인 인기를 얻고 있습니다.
이 문장이 가장 와닿았습니다. 제가 느꼈던 변화가 단순히 개인적인 취향의 변화가 아니라 개발 생태계 전체의 흐름같다고 느끼기도 했습니다.
흥미로운 점은 StyledComponents 팀이 기존 API나 기능을 근본적으로 변경하지 않기로 결정했다는 점입니다. 메인테이너가 모든 것을 변경하여 대규모 마이그레이션 부담을 주는 일이 발생하기도 합니다. 이런 불편함을 기존 사용자에게 안기지 않도록 가끔씩 버그 수정과 기타 개선 사항을 제공하며 유지보수 모드로 전환한다는 점이 따뜻한 마지막 인사처럼 느껴졌습니다.
이런 상황을 보면서 개발자로서 느끼는 것은 기술의 유행과 흐름이 얼마나 빠르게 변하는지, 그리고 그 속에서 우리가 얼마나 유연하게 적응해야 하는지에 대한 중요성입니다. 한때 혁신적이었고 많은 개발자들이 사랑했던 StyledComponents와 CSS in JS 패러다임이 이제는 새로운 도전에 직면하고 있습니다.
그렇다고 CSS in JS가 완전히 사라질 것이라고 생각하지는 않습니다. 여전히 많은 프로젝트에서 사용되고 있고, 특정 상황에서는 최적의 솔루션일 수 있습니다. 하지만 새로운 프로젝트에서는 tailwind와 같은 대안을 고려하는 것이 현명한 선택일 수도 있겠다는 생각이 듭니다.
떠나간 StyledComponents, 그리고 찾아온 tailwind. 이 두 기술 모두 각자의 시대에 빛났고, 개발자인 저에게 많은 것을 가르쳐 주었습니다. 다음 글은 이어서 찾아온 tailwind에 대해서 적어보도록 하겠습니다.