Mantine
Mantine works in NiteFx the way its Vite guide sets it up: its stylesheet imported from code, postcss-preset-mantine for your own CSS modules, and optionally Sass with Mantine's helpers.
Install
nite add @mantine/core @mantine/hooks
nite add -D postcss postcss-preset-mantine postcss-simple-vars
Add other Mantine packages the same way (@mantine/dates, @mantine/notifications, …), each with its own stylesheet import.
PostCSS
Create Client/postcss.config.cjs, exactly as in Mantine's guide:
module.exports = {
plugins: {
"postcss-preset-mantine": {},
"postcss-simple-vars": {
variables: {
"mantine-breakpoint-xs": "36em",
"mantine-breakpoint-sm": "48em",
"mantine-breakpoint-md": "62em",
"mantine-breakpoint-lg": "75em",
"mantine-breakpoint-xl": "88em",
},
},
},
};
The provider and styles
Import Mantine's styles once, before your own, and wrap the app in MantineProvider:
// Client/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "@mantine/core/styles.css";
import { MantineProvider } from "@mantine/core";
import { App } from "./App";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<MantineProvider>
<App />
</MantineProvider>
</StrictMode>,
);
Your own styles
CSS modules get everything postcss-preset-mantine provides: rem() and em(), light-dark(), alpha(), and the dark, light, hover, rtl and breakpoint mixins.
/* Client/Card.module.css */
.card {
padding: rem(20px);
border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
background: alpha(var(--mantine-color-blue-6), 0.1);
@mixin hover {
background: alpha(var(--mantine-color-blue-6), 0.2);
}
@media (max-width: $mantine-breakpoint-sm) {
padding: rem(8px);
}
}
import { Button, Text } from "@mantine/core";
import classes from "./Card.module.css";
export function Card() {
return (
<div className={classes.card}>
<Text>Hello from Mantine</Text>
<Button>Click me</Button>
</div>
);
}
With Sass
Mantine's Sass guide shares a _mantine.scss file of helpers through additionalData. Install Sass and put the file in the client root:
nite add -D sass-embedded
// Client/_mantine.scss
@use "sass:math";
$mantine-breakpoint-md: "62em";
@function rem($value) {
@return #{math.div(math.div($value, $value * 0 + 1), 16)}rem;
}
@mixin dark {
[data-mantine-color-scheme="dark"] & {
@content;
}
}
@mixin smaller-than($breakpoint) {
@media (max-width: $breakpoint) {
@content;
}
}
Then share it with every Sass file. Where Vite's config builds an absolute path, NiteFx only needs the name, because the client root is a Sass load path:
{
"css": {
"preprocessorOptions": {
"scss": { "additionalData": "@use \"mantine\" as mantine;" }
}
}
}
// Client/Hero.module.scss
.title {
font-size: mantine.rem(48px);
@include mantine.dark {
color: white;
}
@include mantine.smaller-than(mantine.$mantine-breakpoint-md) {
font-size: mantine.rem(24px);
}
}
PostCSS still runs after Sass, so light-dark() and the other preset functions work in .scss files too.
Importing a Mantine Vite app
nite init my-app --from ../my-mantine-app carries the whole setup over: the dependencies, postcss.config.cjs, and the additionalData from vite.config (it understands the path.join(process.cwd(), 'src/_mantine') form in Mantine's guide). See Importing a project.
Notes
- Mantine's own stylesheets (
@mantine/core/styles.css) are already built, so NiteFx does not run PostCSS over them. That keeps startup fast; the result is identical. @mantine/core/styles.layer.css(the cascade-layer variant) works the same way.- Hot updates work for all of it: CSS modules refresh their components with state kept, and editing
_mantine.scssorpostcss.config.cjsupdates every stylesheet that used it.