Integrate Remix with vanilla-extract.
Open this example on CodeSandbox:
This example shows how to use vanilla-extract in Remix. Vanilla-extract is a zero-runtime CSS-in-TypeScript library that converts .css.ts
files into static CSS at build time, providing first-class support for local-scoping of classes, variables, themes and more.
- A separate tsup process is needed to generate CSS, JavaScript and type definitions, whereas vanilla-extract is typically hooked up to your bundler. Effectively we're treating vanilla-extract more like a traditional CSS preprocessor like Sass or Less.
- All styles from
.css.ts
files need to be manually re-exported from/.styles/index.ts
which is then compiled into/app/styles
for the Remix app to consume. You can think of it as maintaining a style manifest file. Conceptually this is the same as writing anindex.scss
file in Sass, except that JavaScript code and type definitions are generated in addition to CSS. - All styles are built into
/app/styles/index.css
which your Remix app needs to include via alinks
function. - Remix app code always needs to import styles from
~/styles
, even if a.css.ts
file is in the same directory as the Remix code that imports it. If you don't do this, your vanilla-extract styles won't be compiled properly as they will go directly through the Remix compiler. - You can keep the file size down using Sprinkles which generates compression-friendly atomic CSS. You can then access these classes at runtime via the type-safe
sprinkles
function. - To reduce boilerplate in your React code, Sprinkles can be wired up to a
Box
component as demonstrated in this project, allowing you to access atomic styles via props.
- tsup.config.js where tsup is configured with the vanilla-extract esbuild plugin.
- package.json where tsup is hooked up to the
dev
andbuild
scripts using npm-run-all. - .styles/index.ts where everything generated by vanilla-extract is re-exported for the Remix app to consume.
- .styles/global.css.ts where global styles are defined.
- .styles/sprinkles.css.ts where utility classes are configured using Sprinkles.
- app/root.tsx where the generated CSS file is imported into the Remix app.
- app/components/Box/Box.ts where the utility classes generated by Sprinkles are hooked up to a primitive
Box
component. - app/components/Text/Text.tsx where you can see an example of component-level styles being imported from
~/styles
. - app/components/Text/Text.css.ts where you can see an example of component-level styles being defined.
- .eslintrc where everything in the generated
/app/styles
directory is added to ESLint'signorePatterns
. - .gitignore where the generated
/app/styles
directory is added to the ignore list.