Research
Security News
Kill Switch Hidden in npm Packages Typosquatting Chalk and Chokidar
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
ainsley
ainsley
is a more efficient way to define your stylesheet.
It promises to let you:
// Define your stylesheet using JavaScript, or JSON
const breakpoints = Object.entries({
s: 384,
m: 768,
l: 1024
}).map(([prefix, pixels]) => [prefix, `@media(min-width:${pixels}px)`])
// This tiny object contains all the instructions to assemble a stylesheet
const ainsley = {
// `variations` allow you to add modifiers to children
// e.g. breakpoints, or hover styles
variations: [breakpoints],
// `variables` allow you to reuse groups of properties and values
variables: {
color: { b: 'black', w: 'white' }
},
children: [
// You may use `"$..."` syntax to import configs and remote urls;
// it is able to import CSS and JSON.
'$https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css',
// You may also use it to import configs installed by npm (or yarn);
// this one would import the npm package "ainsley-config-example".
'$example',
// You may nest ainsley objects;
// this allows you to scope variables, variations and configs.
{
variables: {
// `variables` prefixed with a `+` will merge with any
// definition higher up (otherwise, it behaves like normal).
'+color': {
lg: '#eee',
g: '#888',
dg: '#222'
},
// `variables` prefixed with a `?` will only be defined
// if they have not been already been defined higher up.
'?length': {
0: 0,
1: '1px',
2: '2px'
}
},
children: [
// This is a "utility rule" - it looks like a typical CSS rule.
// It uses a variable, which will output every possible permutation!
['bg', [['background-color', '{color}']]],
// This string is the prefix of the "utility class".
// โ Abbreviations of `variable` values will be appended to it.
[
'b',
[
// "Utility rules" support multiple declarations.
// "Utility declarations" may use any number of variables.
['border', '{length} {color}'],
['border-style', 'solid']
]
]
]
}
]
}
// flatten replaces external dependencies with their contents
// (i.e. CSS/JSON urls, configs)
// ๐ โก ๐
const configWithoutDependencies = await flatten(ainsley)
// minify generates a config which is designed to use less bytes
// after it has been compressed; this is how it should be sent to the client
// ๐ โก ๐
const minifiedConfig = minify(configWithoutDependencies)
// (ON THE CLIENT) to generate CSS, and embed it into the page
// ๐ โก ๐งก๐๐๐๐
Ainsley.embed(Ainsley.generate(minifiedConfig /* , options */))
Instead of writing a stylesheet in CSS, you write it in a small JavaScript object, which can be optionally serialized as JSON.
The browser receives this small object and recursively compiles it into CSS. This compresses it massively.
โโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโโโ
โ JS โ JS-to-CSS โ Equivalent โ
โ input โ compiler โ CSS output โ
โโโโโโโโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโโค
โ minified bytes โ 5,094 โ 2,751 โ 786,877 โ
โโฌโโโโโโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโโค
โ gzipped bytes โ 2,146 โ 1,317 โ 139,296 โ
โโฌโโโโโโโโโโโโโโโผโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโโค
โ brotli bytes โ 1,821 โ 1,163 โ 23,747 โ
โโโฌโโโโโโโโโโโโโผโโโโโโโโดโโโโโโโโโโโโผโโโโโโโโโโโโโค
โ TOTAL SENT โ 2,984 โ 23,747 โ
โโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโ
(using default settings with ainsley-config-starter)
Name | Minified | Gzip | Brotli | CSS Rules | Rules per byte |
---|---|---|---|---|---|
ainsley | 7,845 | 3,463 | 2,984 | 22,809 | 7.64 |
tailwindcss | 710,997 | 97,417 | 10,199 | 14,445 | 1.42 |
tachyons | 73,497 | 13,697 | 2,421 | 2,113 | 0.87 |
sane-tachyons | 49,793 | 9,200 | 1,957 | 1,278 | 0.65 |
turretcss | 93,542 | 17,025 | 4,311 | 1,588 | 0.37 |
solid | 82,482 | 12,585 | 2,497 | 1,469 | 0.59 |
basscss | 11,326 | 2,477 | 589 | 260 | 0.44 |
bootstrap | 159,515 | 23,681 | 4,762 | 2,027 | 0.43 |
bulma | 194,420 | 25,511 | 5,705 | 2,142 | 0.38 |
materialize | 141,841 | 21,558 | 5,579 | 1,609 | 0.29 |
spectre | 45,964 | 9,631 | 1,992 | 638 | 0.32 |
foundation | 132,474 | 17,219 | 3,471 | 1,420 | 0.41 |
milligram | 8,718 | 2,295 | 442 | 90 | 0.20 |
skeleton | 5,879 | 1,630 | 356 | 84 | 0.24 |
ainsley-loader
to write your config in a .ainsley
fileainsley
- embed and gradually migrateainsley
- compile, embed and gradually migrateIf you'd like to help, send me a message! ๐จ๐พโ๐ณ
I didn't make this project to make money, but donating can help keep projects like this maintained properly. Contribute
Or perhaps you might like to donate to a top rated charity instead (they need the money more!)
FAQs
๐จ๐พโ๐ณ Ainsley is to CSS what Markdown is to HTML
We found that ainsley demonstrated a not healthy version release cadence and project activity because the last version was released a year ago.ย It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.