How Styled-Components Works Under the Hood and Building a Minimal CSS‑in‑JS Library
This article explores the inner workings of styled-components, examines its core source code, and demonstrates how to build a lightweight CSS‑in‑JS library for SolidJS, while discussing the benefits and drawbacks of CSS‑in‑JS approaches in modern front‑end development.
Preface
The author recently learning Material UI discovered that its components are built with CSS‑in‑JS, which sparked curiosity about how CSS‑in‑JS libraries operate and why Material UI chose this approach, leading to an exploration and the creation of a personal CSS‑in‑JS library.
Research
Two popular CSS‑in‑JS libraries are
emotionand
styled-components. Their APIs are largely identical, but the author abandoned
emotiondue to its mixed JavaScript, Flow, and TypeScript source, and selected
styled-componentsas the study target.
styled-components Core Capabilities
Usage
Opening the official documentation, navigating to Documentation → API Reference, the first core API shown is
styled. Example usage with template literals:
<code>const Button = styled.div`
background: palevioletred;
border-radius: 3px;
border: none;
color: white;
`;</code>This creates a React component with embedded styles.
Digging Deeper
Cloning the GitHub repo reveals that
styled-componentsis a monorepo; the core package shares the repo name. The default export
styledoriginates from
src/constructors/styled.tsx.
Inspecting
src/constructors/styled.tsx, the simplified code is:
<code>import createStyledComponent from '../models/StyledComponent';
import domElements from '../utils/domElements';
import constructWithOptions from './constructWithOptions';
const baseStyled = (tag) => constructWithOptions(createStyledComponent, tag);
const styled = baseStyled;
domElements.forEach(domElement => {
styled[domElement] = baseStyled(domElement);
});
export default styled;</code>The
styledAPI essentially provides a shortcut
styled[HTMLElement]for rapid component creation.
Core Source
The
constructWithOptionsfactory returns a template function that invokes the component constructor with CSS processing. Simplified:
<code>export default function constructWithOptions(componentConstructor, tag, options) {
const templateFunction = (initialStyles, ...interpolations) =>
componentConstructor(tag, options, css(initialStyles, ...interpolations));
return templateFunction;
}</code>Thus
baseStyledis built by this factory.
Further up the chain, the component constructor is
createStyledComponent, which returns a
WrappedStyledComponentcreated with
React.forwardRefand utilizes the hook
useStyledComponentImpl.
The hook
useInjectedStylecreates a
Taobao Frontend Technology
The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.