SWC plugin for styled-components that provides transformation support with displayName generation, SSR support, and minification capabilities
npx @tessl/cli install tessl/npm-swc--plugin-styled-components@9.1.0SWC plugin that provides build-time transformations for styled-components library. This plugin operates as a WebAssembly-compiled transformation plugin for SWC, offering features like displayName generation for debugging, server-side rendering support, CSS minification, template literal processing, and JSX css prop transformation.
npm install --save-dev @swc/plugin-styled-components @swc/coreThis plugin operates as a SWC transform plugin and is configured in the SWC configuration rather than imported directly in code:
{
"jsc": {
"experimental": {
"plugins": [
["@swc/plugin-styled-components", { /* options */ }]
]
}
}
}Basic plugin configuration with common options:
{
"jsc": {
"experimental": {
"plugins": [
[
"@swc/plugin-styled-components",
{
"displayName": true,
"ssr": true,
"minify": true,
"cssProp": true
}
]
]
}
}
}Example code transformation:
// Input code
import styled from "styled-components";
const Button = styled.button`
background: blue;
color: white;
`;
// Output with displayName and SSR enabled
import styled from "styled-components";
const Button = styled.button.withConfig({
displayName: "Button",
componentId: "sc-1234567890"
})`background:blue;color:white;`;Plugin configuration options control the transformation behavior. Note that configuration is provided as JSON in the SWC config file, using camelCase field names.
interface Config {
/** Add displayName for debugging (default: true) */
displayName?: boolean;
/** Enable server-side rendering support (default: true) */
ssr?: boolean;
/** Include filename in component ID (default: true) */
fileName?: boolean;
/** Files considered meaningless for naming (default: ["index"]) */
meaninglessFileNames?: string[];
/** Component namespace prefix (default: "") */
namespace?: string;
/** Import paths to process (default: []) */
topLevelImportPaths?: string[];
/** Transform template literals (default: true) */
transpileTemplateLiterals?: boolean;
/** Minify CSS in template literals (default: true) */
minify?: boolean;
/** Add pure annotations for dead code elimination (default: false) */
pure?: boolean;
/** Transform JSX css prop (default: true) */
cssProp?: boolean;
}Configuration Examples:
// Full configuration with all options
{
"jsc": {
"experimental": {
"plugins": [
[
"@swc/plugin-styled-components",
{
"displayName": true,
"ssr": true,
"fileName": true,
"meaninglessFileNames": ["index", "styles"],
"namespace": "myapp",
"topLevelImportPaths": ["styled-components"],
"transpileTemplateLiterals": true,
"minify": true,
"pure": false,
"cssProp": true
}
]
]
}
}
}
// Development configuration (enhanced debugging)
{
"jsc": {
"experimental": {
"plugins": [
[
"@swc/plugin-styled-components",
{
"displayName": true,
"ssr": false,
"minify": false,
"pure": false
}
]
]
}
}
}
// Production configuration (optimized)
{
"jsc": {
"experimental": {
"plugins": [
[
"@swc/plugin-styled-components",
{
"displayName": false,
"ssr": true,
"minify": true,
"pure": true
}
]
]
}
}
}Automatically adds displayName property to styled components for better debugging experience in React DevTools.
Input:
import styled from "styled-components";
const Button = styled.button`
padding: 8px 16px;
`;
const Header = styled.h1`
font-size: 24px;
`;Output (with displayName: true):
import styled from "styled-components";
const Button = styled.button.withConfig({
displayName: "Button"
})`padding:8px 16px;`;
const Header = styled.h1.withConfig({
displayName: "Header"
})`font-size:24px;`;Configuration:
displayName: booleantrueGenerates stable component IDs for consistent rendering between server and client.
Input:
import styled from "styled-components";
const Container = styled.div`
max-width: 1200px;
`;Output (with ssr: true):
import styled from "styled-components";
const Container = styled.div.withConfig({
displayName: "Container",
componentId: "sc-1a2b3c4d"
})`max-width:1200px;`;Configuration:
ssr: booleantrueMinifies CSS content within template literals to reduce bundle size.
Input:
const Button = styled.button`
background: linear-gradient(
to right,
#ff6b6b,
#4ecdc4
);
padding: 12px 24px;
border-radius: 4px;
border: none;
`;Output (with minify: true):
const Button = styled.button.withConfig({
displayName: "Button",
componentId: "sc-1a2b3c4d"
})`background:linear-gradient(to right,#ff6b6b,#4ecdc4);padding:12px 24px;border-radius:4px;border:none;`;Configuration:
minify: booleantrueTransforms JSX css prop into styled components for runtime optimization.
Input:
const MyComponent = () => (
<div css="color: red; font-size: 16px;">
Hello World
</div>
);
const DynamicComponent = ({ color }) => (
<p css={`color: ${color}; font-weight: bold;`}>
Dynamic styling
</p>
);Output (with cssProp: true):
const MyComponent = () => (
<StyledDiv>
Hello World
</StyledDiv>
);
const DynamicComponent = ({ color }) => (
<StyledP color={color}>
Dynamic styling
</StyledP>
);
const StyledDiv = styled.div`color:red;font-size:16px;`;
const StyledP = styled.p`color:${props => props.color};font-weight:bold;`;Configuration:
cssProp: booleantrueAdds /#PURE/ comments for dead code elimination by bundlers.
Input:
import styled, { css, keyframes } from "styled-components";
const Button = styled.button`
color: blue;
`;
const fadeIn = keyframes`
from { opacity: 0; }
to { opacity: 1; }
`;Output (with pure: true):
import styled, { css, keyframes } from "styled-components";
const Button = /*#__PURE__*/ styled.button.withConfig({
displayName: "Button"
})`color:blue;`;
const fadeIn = /*#__PURE__*/ keyframes`
from { opacity: 0; }
to { opacity: 1; }
`;Configuration:
pure: booleanfalseProcesses and optimizes template literals in styled components.
Configuration:
transpileTemplateLiterals: booleantrueAdds custom namespace prefix to component IDs for preventing conflicts.
Configuration:
namespace: string""Example:
{
"jsc": {
"experimental": {
"plugins": [
[
"@swc/plugin-styled-components",
{
"namespace": "myapp"
}
]
]
}
}
}Controls whether filename is included in component ID generation.
Configuration:
fileName: booleantrueSpecifies filenames that should be ignored for component naming purposes.
Configuration:
meaninglessFileNames: string[]["index"]Specifies which import paths should be processed by the plugin.
Configuration:
topLevelImportPaths: string[][]The plugin will terminate the build process if:
deny_unknown_fields setting)Configuration errors result in build failures with descriptive messages from the SWC runtime. Ensure your plugin configuration follows the exact field names and types shown in the Config interface above.
The plugin is distributed as a self-contained WebAssembly binary with no additional runtime dependencies required in the target project.
// Different configs per environment
{
"env": {
"development": {
"jsc": {
"experimental": {
"plugins": [
[
"@swc/plugin-styled-components",
{
"displayName": true,
"ssr": false,
"minify": false
}
]
]
}
}
},
"production": {
"jsc": {
"experimental": {
"plugins": [
[
"@swc/plugin-styled-components",
{
"displayName": false,
"ssr": true,
"minify": true,
"pure": true
}
]
]
}
}
}
}
}Next.js:
// next.config.js
module.exports = {
experimental: {
swcPlugins: [
[
"@swc/plugin-styled-components",
{
displayName: true,
ssr: true
}
]
]
}
};Webpack with SWC:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(js|ts|jsx|tsx)$/,
use: {
loader: '@swc/loader',
options: {
jsc: {
experimental: {
plugins: [
[
"@swc/plugin-styled-components",
{
displayName: process.env.NODE_ENV === 'development',
ssr: true,
minify: process.env.NODE_ENV === 'production'
}
]
]
}
}
}
}
}
]
}
};