
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
vite-plugin-toad
Advanced tools
Zero-runtime CSS-in-JS tool inspired by Linaria.
Try on StackBlitz or check out example.
⚠ Work in progress.
pnpm i -D vite-plugin-toad
/*@toad-ext .scss*/ // This sets extension for corresponding output file.
// You can set in plugin config globally or for each file.
import { render } from 'solid-js/web';
import { modularScale, hiDPI } from 'polished';
import { css } from 'vite-plugin-toad/css';
import Constants from './constants';
import logo from './logo.svg';
css`/*global*/ /* mark style as global */
body {background-color: ${Constants.BACKGROUND_COLOR};} /* Use some static variables. Works when 'ssr.evaluate = true' */
@keyframes logo-spin {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
`;
const App = () => (
<div
class={css`
/*@toad-debug wrapper*/ // <- this adds "wrapper" to output class
max-width: 800px;
background-color: #dadada;
font-size: ${modularScale(2)};
${hiDPI(1.5)} {
font-size: ${modularScale(2.5)};
}
`}
>
<img
src={logo}
class={css`
animation: logo-spin infinite 10s linear;
height: 40vmin;
pointer-events: none;
& ~ p {
$variable: blue;
color: #{$variable}; // This code will work as we set .scss extension
}
`}
/>
<p>Edit <code>app.tsx</code> and save to reload</p>
<a href="https://github.com/solidjs/solid" target="_blank" > Learn solid </a>
</div>
);
if (!import.meta.env.SSR) {
render(App, document.body);
}
All CSS transforms are handled by Vite, so it will work with SASS, LightningCSS, PostCSS and other tools.
There is also way to write your CSS-in-JS separately by using babel-plugin-css-attribute. Here it is an example from my project with UnoCSS, preset attributify and vite-plugin-toad:
<a
m-b-8
m-t-16px
class="block cursor-pointer text-center c-blue-500"
css={css`@container (height < 400px) { margin-bottom: 0; }`}
>
My link
</a>
⬇️vite-plguin-toad⬇️
<a class={"block cursor-pointer text-center c-blue-500 m-b-8 m-t-16px" + "login_page-1okjy9f"}
>
My link
</a>
To use this feature, set transformCssAttribute: true or use Babel plugin, example with vite-plugin-solid:
import ViteSolid from "@foxpro/vite-plugin-solid"
import BabelPluginCssAttrs from "vite-plugin-toad/babel-plugin-css-attribute"
// ...vite configurations and plugins...
ViteSolid({
hot: dev,
dev: dev,
typescript: {
onlyRemoveTypeImports: true
},
babel: {
plugins: [[BabelPluginCssAttrs, {}]]
}
})
⚠️ To achieve better better performance, use
babel-plugin-css-attributedirectly if possible, because Toad will use additionally:
@babel/preset-typescript
@babel/plugin-syntax-jsx
This can slightly affect build performance.
You can customize babel options by usingbabeloption.
For more advanced documentation, please refer to typescript JSDoc comments.
I found following way of writing components can be convinient:
<TextField.Input
ref={numberInputRef}
inputmode="decimal"
css="
background-color: var(--grey-000);
border: 1px solid blue; border-radius: 8px;
&:focus {
outline-offset: -5px; outline-color: var(--grey-000);
}
color: var(--black-900); line-height: 3.5rem; font-weight: 500;
"
h-12 w-full p-l-10px
/>
CSS-in-JS for creating component styles, and Atomic CSS with attributify for positioning component in layout.
I found this way keeps code more clean and readable. It avoids mess of long atomic classes with ?#[]@ symbols and decoupling of styles as it used to with BEM or CSS modules.
I'm planning to add handling of css="" attribute.
Make sure you modules with CSS-in-JS don't use top-level DOM API if you are using ssr: { eval: true }. You can wrap it like in the example:
if (!import.meta.env.SSR) {
render(App, document.body)
}
Some plugins don't respect Vite ssr: true option when using ssrLoadModule, so they need to be processed separately if you're want to use variables in template literals.
You can process it in customSSRTransformer. Make sure to output SSR-ready code.
ViteToad({
outputExtension: '.scss',
exclude: [/node_modules/, /\.s?css/], // better to exclude all styles
ssr: {
eval: true,
async customSSRTransformer(code, ctx, server, _c, url) {
solidOptions.solid.generate = 'ssr'
const result = await server.transformRequest(skipToadForUrl(url), { ssr: true })
// Or, if you know what you're doing:
// const solidPlugin = server.config.plugins.find(p => p.name === 'solid')
// const result = await solidPlugin.transform(code, skipToadForUrl(url), { ssr: true })
return {
result,
// this will be called when we will transform all dependencies
cb: () => {
solidOptions.solid.generate = 'dom'
}
}
},
},
})
Currently, it may not work if styles are co-located with some legacy dependencies / or dependencies that are not intended to be used in SSR environment. What you can do about it:
import() inside your component near usage place, or in if(!import.meta.env.SSR).load() hook.ssr.external configuration.
It's possible that I will implement some kind of tree-shaking through SWC, so all unused in styling deps will be omitted, as Linaria do with their shaker.You can avoid using import { css } from 'vite-plugin-toad/css by adding "vite-plugin-toad/css" entry to tsconfig.json compilerOptions.types array.
FAQs
Zero runtime CSS-in-JS powered by Vite
We found that vite-plugin-toad 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.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.