magnostic 🧲
![license](https://badgen.net/npm/license/magnostic)
magnostic is an opinionated bundler-agnostic lightweight CSS-in-JS utility using css
paradigm.
Install
npm install magnostic
Why another CSS-in-JS library ?
I'm using Emotion on a daily basis in professional and hobby React, Svelte and Vue projects.
CSS-in-JS is a great tool, and I enjoy using framework-agnostic css
paradigm since it can be used in basically any framework. But once you start using Server-Side Rendering, it becomes a mess, especially if not using Babel or React.
Some issues with existing libraries
Notice: Following mentionned snippets are subject to change.
- Emotion API is quite confusing [1] [2], there are currently two
css
paradigms (emotion
[3] and @emotion/css
[4]) which don't do the same thing. Emotion 11 is on the way [5] with lots of API reworks but I'll remain cautious linaria
has Babel as a peer dependency [6] and is mostly designed to be used with this tool [7]styled-components
has React and React DOM as peer dependencies [8] and has a css
paradigm which requires a Babel pluginmonad-ui
has @emotion/core
, React and React DOM as peer dependencies [9]jss
[10] , aphrodite
[11] and many others don't support template literalsgoober
does have convenient extractCss
method [12] but its css
paradigm lacks testing and features like composition [13]picostyle
only supports frameworks with JSX pragmas [14]
Features
- Similar Emotion API (nesting, composition, etc.)
- Bundler-agnostic
- Framework-agnostic
- Debugging
- Isolated stores
- Media queries (
@media
) - Extract CSS
- Keyframes (
@keyframes
)
To be implemented
- Merge duplicate/overwritten styles
- Object styles
- Convert tagged templates ⬌ object styles
API
css(template,...props)
@returns {MagnosticStyle}
Style object with unique identifier
The default css
method expects a tagged template literal as input, which may include variables or other magnostic styles passed via placeholders ${}
.
import {css} from 'magnostic'
const style = css`
color: blue;
`
console.log(`${style}`)
console.log(style)
Compared to Emotion, magnostic makes no assumption and still let users have control and visibility upon generated styles if explicitly asked to, using a regular console.log
for example.
import {css} from 'emotion'
const style = css`
color: blue;
`
console.log(`${style}`)
console.log(style)
keyframes(template,...props)
@returns {MagnosticKeyframes}
Keyframes object with unique identifier
Similar to Emotion's keyframes
method, the default keyframes
method allows to explicitly register a CSS animation with an unique identifier, using a template literal as input.
import {css, keyframes, extractCss} from 'magnostic'
const slideIn = keyframes`
from {
left: 100%;
}
to {
left: 0%;
}
`
console.log(`${slideIn}`)
Then, the animation can be used as a style rule.
const slidingText = css`
animation: ${slideIn} 1s ease infinite;
`
console.log(extractCss())
@returns {string}
Returns the generated CSS code
Similar to goober
's extractCss
method, this outputs generated CSS from all previous default css
and keyframes
method calls.
import {css, extractCss} from 'magnostic'
const blueText = css`
color: blue;
`
const cyanText = css`
color: cyan;
`
console.log(extractCss())
createStore()
@returns {MagnosticStore}
Returns the generated store, including various methods
magnostic does provide a default css
method which pushes any generated style to a global store, but still allows anyone to create their own stores, which all provide isolated methods (css
, extractCss
, keyframes
, etc.). This is particularly useful when creating view-specific style rules and/or when trying to reduce bundle sizes.
import {createStore} from 'magnostic'
const someStore = createStore()
const { css, extractCss } = someStore
const blueText = css`
color: blue;
`
const anotherStore = createStore()
const { css: css2, extractCss: extractCss2 } = anotherStore
const centerAlignedText = css2`
text-align: center;
`
console.log(extractCss())
console.log(extractCss2())
Contributing
magnostic is based on stylis
(like Emotion) and has a TypeScript codebase, there are some useful npm
scripts :
npm run build
— Use tsup
and esbuild
to bundle library and generate typingsnpm run test
— Build then run tests with uvu
npm run lint
— Run linting checks with xo
and fix common issues