Styled System
A maintained, first-class-TypeScript rewrite of styled-system v5 - responsive, theme-aware style props for CSS-in-JS.
It is a drop-in replacement for the styled-system runtime: the root export surface matches upstream verbatim, and the package ships its own types (replacing @types/styled-system).
Features
- Add style props that hook into your own theme
- Quickly set responsive
font-size,margin,padding,gap,width, and more with props - Influenced by constraint-based design-system principles
- Typographic scale, and a spacing scale for
margin,paddingandgap - Works with any color palette
- Works with most CSS-in-JS libraries, including Emotion and styled-components
- First-class TypeScript types - theme-scale-aware props, replacing
@types/styled-system
Install
# npm
npm install @soroush.tech/styled-system
# pnpm
pnpm add @soroush.tech/styled-system
# yarn
yarn add @soroush.tech/styled-system
@emotion/is-prop-valid (^1.4.0, peer) and prop-types (^15.8.1, optional peer) are
each used by a single subpath - should-forward-prop and prop-types
respectively. Install one only if you import that subpath. You bring your own CSS-in-JS
library (Emotion, styled-components, ...); the core carries neither at runtime.
Usage
// Example uses Emotion, but styled-system works with most other CSS-in-JS libraries as well
import styled from '@emotion/styled'
import { space, layout, typography, color } from '@soroush.tech/styled-system'
// Add styled-system functions to your component
const Box = styled.div`
${space}
${layout}
${typography}
${color}
`
Each style function exposes its own set of component props that handle styles based on values defined in a theme.
// width: 50%
<Box width={1 / 2} />
// font-size: 20px (theme.fontSizes[4])
<Box fontSize={4} />
// margin: 16px (theme.space[2])
<Box m={2} />
// padding: 32px (theme.space[3])
<Box p={3} />
// color
<Box color="tomato" />
// color: #333 (theme.colors.gray[0])
<Box color="gray.0" />
// background-color
<Box bg="tomato" />
Responsive style props
Set responsive width, margin, padding, font-size, and other properties with a shorthand array syntax. See Responsive Styles.
// responsive width
<Box width={[1, 1 / 2, 1 / 4]} />
// responsive font-size
<Box fontSize={[2, 3, 4]} />
// responsive margin
<Box m={[1, 2, 3]} />
// responsive padding
<Box p={[1, 2, 3]} />
Subpath imports
Subpaths mirror the original @styled-system/* packages:
import { css } from '@soroush.tech/styled-system/css'
import { themeGet } from '@soroush.tech/styled-system/theme-get'
import { pick, omit } from '@soroush.tech/styled-system/props'
import propTypes, { createPropTypes } from '@soroush.tech/styled-system/prop-types'
import shouldForwardProp, {
createShouldForwardProp,
props,
} from '@soroush.tech/styled-system/should-forward-prop'
Drop-in via alias
Existing styled-system users can swap with a package-manager alias - no code changes:
"dependencies": {
"styled-system": "npm:@soroush.tech/styled-system@^5"
}
The satellite @styled-system/* packages don't need separate aliases - import them as
subpaths off the aliased styled-system name, and they resolve through this package's
exports:
import themeGet from 'styled-system/theme-get'
import propTypes from 'styled-system/prop-types'
import { css } from 'styled-system/css'
import shouldForwardProp from 'styled-system/should-forward-prop'
Types resolve under both modern module resolution (node16/nodenext/bundler, via
exports) and classic node (via typesVersions).
Documentation
Full docs live in docs/:
- Getting Started
- Responsive Styles
- How it Works
- Custom Props
- Variants
- API
- Reference Table
- TypeScript
- Guides
Runnable demos live in the examples repo.
Release notes
Per-version notes for every published release live in
release-notes/.
License
MIT - a rewrite of styled-system (© 2017-2021 Brent Jackson), see LICENSE.
Releases
@soroush.tech/[email protected]
Maintenance release. No public API, behavior, or emitted-output changes - comments and docs only. No scale, prop, or generated style changed.
@soroush.tech/[email protected]
Maintenance release - build tooling only. No public API, behavior, or type changes. (#328)
Packaging
- The workspace moved its formatter from Prettier to
oxfmt, which wraps multi-line union types onto leading-pipe lines. That reformatted theObjectOrArraydeclaration insrc/types.ts; the type it describes is unchanged. No source, runtime, peer, or dev dependency changes. typescriptmoves to~7.0.2. It is a dev dependency here, used to typecheck and emit; the emitted output is unchanged.
@soroush.tech/[email protected]
Maintenance release - dependency refresh only. No public API or behavior changes. (#280)
Packaging
- Dev-dependency bumps:
eslint^10.7.0→^10.8.0,globals^17.7.0→^17.9.0,tsdown^0.22.7→^0.22.14. No runtime or peer dependency changes.
@soroush.tech/[email protected]
Scale flex and grid gaps on space, add aspectRatio to layout, and add whiteSpace and
textOverflow to typography - six props the original styled-system never shipped. Additive and
backward-compatible.
(#313)
Added
gap,rowGap,columnGap- resolve againsttheme.space, the same scale (and default scale) as margins and paddings, and compose intospacealongsidemarginandpadding. Upstream only ever scaled the grid-prefixedgridGap/gridRowGap/gridColumnGap, so flex gaps had to be hand-wired throughsystem(); that custom mapping can go. Typed viaGapProps/RowGapProps/ColumnGapProps, composed intoSpaceProps. Thegapparser is also exported standalone, alongsidemarginandpadding.aspectRatio- maps straight to CSSaspect-ratio(no theme scale). Upstream's last release predates the property, so this too was hand-wired; that mapping can go as well. Typed viaAspectRatioProps, composed intoLayoutPropsand re-exported from the/layoutsubpath.whiteSpaceandtextOverflow- map straight to CSSwhite-spaceandtext-overflow(no theme scale). Together withoverflowfromlayoutthey make text truncation expressible in props alone, instead of dropping into raw CSS for the one declaration the parser was missing. Typed viaWhiteSpaceProps/TextOverflowProps, composed intoTypographyPropsand re-exported from the/typographysubpath, with both parsers also exported standalone alongsidetextAlignandtextTransform.- All support responsive array and breakpoint-object values, and are filtered from the DOM
automatically - none needs adding to a
shouldForwardPropblocklist, sincepropsderives fromall.propNames. - Docs: Space props reference · Layout props reference · Typography props reference · prop/scale table · theme specification.
Upgrade
- From 5.7.x: drop-in, no code changes. Components that hand-wired
gaporaspectRatiothroughsystem()can delete that mapping and inherit the props fromspace/layout.
Packaging
- No runtime or peer dependency changes.
@soroush.tech/[email protected]
Maintenance release - dependency refresh only. No public API or behavior changes.
Packaging
- Dev-dependency bumps:
tsdown^0.22.4→^0.22.7. No runtime or peer dependency changes.
@soroush.tech/[email protected]
Extend the typography style function with seven text-styling props the original
styled-system never shipped - first-class, theme-aware props alongside textAlign and
fontStyle. Additive and backward-compatible. (#258, #259)
Added
textTransform,textAlignLast,textDecoration,textDecorationLine,textDecorationStyle,textDecorationThickness- raw CSS pass-through props, each exported standalone and folded intoTypographyProps; auto-covered byshould-forward-prop.textDecorationColor- resolves against thecolorstheme scale (likeborderColor), in both the parser and thecss()object-notation path.- Docs: Typography props reference · migration guide.
Upgrade
- From 5.6.x: drop-in, no code changes.
Packaging
- No runtime or peer dependency changes (dev-only tooling bumps).
@soroush.tech/[email protected]
Changes
- Raise
csstyperuntime dependency floor^3.1.3→^3.2.3(newer CSS property typings). - Repository moved to
soroush-tech/core.
No public type or API changes.
@soroush.tech/[email protected]
Completes props-facing type parity with @types/styled-system - closes the drop-in gaps found
migrating a real styled-system v5 monorepo (#215). Recommended upgrade from 5.5.0.
Fixed
themeGetmatches@types/styled-system__theme-getverbatim -(path: string | Array<string | number>, fallback?: any) => (props: any) => any. No moreunknownreturns (TS2339 on destructuring) and no more rejecting component prop interfaces (TS2345). Array paths now also resolve as nested lookups (themeGet(['colors','primary'])), fixing a latent bug the upstream runtime never handled.- Public type surface loosened to
anyto match upstream -Props/Themeindex signatures,Transform/StyleFnparams,StyleObject,ConfigStyle.defaultScale,ThemeValue. Strictunknown/Propsno longer breaks CSS-in-JS interpolation or arbitrary component props. boxShadow/textShadow/fontWeightacceptstring | number- resolves against both object-keyed ({ sm, md }) and array-indexed ([...]) theme scales; restores array-index support that had been dropped.
Added
- Upstream type-name aliases for drop-in imports:
styleFn,Config,ConfigFunction,VariantArgs,LowLevelStyleFunctionArguments.
Changed
@emotion/is-prop-validis now an optional peer dependency (peerDependenciesMeta) - no moremissing peerwarning for consumers who don't use the./should-forward-propsubpath.cssexportsCSSObject(wasCssObject) to match@styled-system/css's actual name.
Upgrade
- From 5.5.0: drop-in, no code changes. This makes the scoped-package migration described in #215 package.json-only.
- 5.5.0 and earlier are deprecated (see notes).
@soroush.tech/[email protected]
Type-resolution fix for classic-node consumers, plus a parity correction to the package root.
Recommended upgrade from 5.4.0 (now deprecated).
Fixed
- Subpath types now resolve under classic
moduleResolution: "node"(node10). Classic resolution doesn't read a package'sexportsmap, sotsccouldn't find types forstyled-system/theme-get,styled-system/prop-types,styled-system/core, etc. (TS2307), even though runtime worked. Added atypesVersionsmap (inpublishConfig) pointing every subpath at its.d.cts- the mechanism classicnodehonors. No consumer changes required (nopaths, nodeclare module, nomoduleResolutionchange). Modern resolution (node16/nodenext/bundler) continues to resolve viaexports.
Removed (parity)
- The package root no longer exports
themeGetor adefault. The originalstyled-systemmain package exports neither - both only ever lived in the standalone@styled-system/theme-get.themeGetremains available (named + default) from the./theme-getsubpath:import themeGet from '@soroush.tech/styled-system/theme-get'.
Docs
- Drop-in guidance now aliases the main
styled-systemname and imports satellites as subpaths off it -import themeGet from 'styled-system/theme-get'- which resolves through this package'sexports(andtypesVersionsfor node10).
Upgrade notes
- From 5.4.0: drop-in. If you imported
themeGetfrom the package root (5.3.0/5.4.0 only), switch to@soroush.tech/styled-system/theme-get. - 5.4.0 is deprecated (root default divergence + the node10 type gap fixed here).
@soroush.tech/[email protected]
Finishes drop-in parity with the styled-system@5 ecosystem - head-to-head is now 16/16 with
the original packages. Builds on 5.3.0 (per-property prop types + Transform fix).
Added
./prop-typessubpath mirroring@styled-system/prop-types:propType,createPropTypes, and a default per-group map (space, color, layout, typography, flexbox, border, background, position, grid, shadow, buttonStyle, textStyle, colorStyle) built from each parser'spropNames. Spread it onto a component:Box.propTypes = { ...propTypes.space, ...propTypes.color }.themeGetas the package-root default export (in addition to the named export added in 5.3.0). A package-manager alias can only bind@styled-system/theme-get→ the package root, soimport themeGet from '@styled-system/theme-get'previously resolved toundefined; bothimport { themeGet }andimport themeGetnow work under the alias.
Notes
- New optional peer dependency
prop-types(^15.8.1) - required only if you import./prop-types. It stays external in the build (~1.6 KB ESM), and the public types use a structural validator so consumers aren't forced to install@types/prop-types. - No runtime behavior change to existing exports; fully backward compatible.
@soroush.tech/[email protected]
Closes the remaining gaps for a true drop-in replacement of styled-system@5 +
@types/styled-system (#213).
Added
- Per-property prop types. Every atomic interface from
@types/styled-systemis now exported (WidthProps,HeightProps,OverflowProps,TopProps,ZIndexProps,AlignItemsProps,JustifyContentProps,FlexProps,FontSizeProps,FontWeightProps,LineHeightProps,TextAlignProps,TextColorProps,BackgroundColorProps,OpacityProps,BorderWidthProps,BorderStyleProps,BorderColorProps,BorderRadiusProps,BorderTop/Right/Bottom/LeftProps,BoxShadowProps,TextShadowProps,TextStyleProps, and the fullGrid*andBackground*families). - Each grouped interface (
LayoutProps,FlexboxProps,BorderProps, ...) now composes its atomic interfaces viaextends, matching upstream's structure. - All types are re-exported from their matching subpath (
./layout,./position,./border, ...) as well as the main entry. themeGetis now also available as a named export from the main entry:import { themeGet } from '@soroush.tech/styled-system'.
Changed
Transformis no longerunknown. It now matches@styled-system/core's(value: any, scale?: any) => any, so consumer transforms like(val) => MAP[val] ?? MAP.centercompile without casts (no more TS2538).
Notes
boxShadow,textShadow, andfontWeightremain intentionally widened over upstream to also acceptstringtheme keys.- No runtime behavior changes; fully backward compatible.
- Still deferred: a
@styled-system/prop-typesequivalent (issue #213 §3).
@soroush.tech/styled-system v5.2.0
The first release of our ground-up rewrite of styled-system - a maintained, first-class-TypeScript implementation of responsive, theme-aware style props for CSS-in-JS.
It's a drop-in replacement for the styled-system v5 runtime: the root export surface
matches upstream verbatim, so existing code keeps working, while everything underneath is new.
Highlights
- Complete TypeScript rewrite - the entire style engine (
system,compose,createParser,createStyleFunction,get) was rebuilt from scratch with first-class types. Every style function carries its own typed prop interface (SpaceProps,ColorProps,LayoutProps, ...). - Ships its own types - no more
@types/styled-system. Types are theme-scale-aware and bundled in the package. - Dual ESM + CJS build with per-category subpath exports (
/space,/color,/layout,/css,/theme-get,/props,/should-forward-prop, ...) mirroring the original@styled-system/*packages. - Tree-shakeable (
"sideEffects": false), zero runtime CSS-in-JS dependency - bring your own Emotion or styled-components. - 100% test coverage, MIT licensed.
⚠️ Breaking change: propTypes dropped
Style functions no longer expose a propTypes property, and there is no prop-types
companion package. The old @styled-system/prop-types is out of scope for this rewrite, and
React 19 removed propTypes for function components entirely.
Migrate by using TypeScript for prop typing - each style function already provides a typed
prop interface, so you get compile-time checking instead of runtime propTypes:
import { space, type SpaceProps } from '@soroush.tech/styled-system'
See the TypeScript guide.
Install
npm install @soroush.tech/styled-system
Existing styled-system users can swap with no code changes via a package-manager alias:
"dependencies": {
"styled-system": "npm:@soroush.tech/styled-system@^5"
}
@emotion/is-prop-valid (^1.4.0) is a peer dependency, needed only if you import the
should-forward-prop subpath.