Usage with Next.js
Next.js integration for WyW is provided via @wyw-in-js/nextjs.
Installation
# npm
npm i -D @wyw-in-js/nextjs
# yarn
yarn add --dev @wyw-in-js/nextjs
# pnpm
pnpm add -D @wyw-in-js/nextjs
# bun
bun add -d @wyw-in-js/nextjsNote: WyW packages are ESM-only and require Node.js
>=22.
Configuration
// next.config.mjs
import { withWyw } from '@wyw-in-js/nextjs';
export default withWyw({
// your Next config
});eval.require defaults to warn-and-run in v2. If eval-time require() happens, WyW will warn and execute it at
runtime; use importOverrides or eval.require: 'error' to make it explicit.
Eval resolver modes
eval.resolver: 'native' and the native step of eval.resolver: 'hybrid' use oxc-resolver with automatic
tsconfig.json discovery, so TypeScript baseUrl/paths aliases work by default.
For the webpack pipeline, @wyw-in-js/webpack-loader forwards static string entries from webpack resolve.alias.
For the Turbopack pipeline configured through withWyw(), static string aliases from turbopack.resolveAlias or
experimental.turbo.resolveAlias are forwarded into native resolver options.
hybrid: trieseval.customResolver, then native resolution, then the active Next bundler resolver. Use this when evaluated imports may depend on Next, webpack, or Turbopack resolver behavior.native: uses onlyoxc-resolver; Next's bundler resolver is not called. Mirror bundler-only aliases inoxcOptions.resolver.aliasor keep usinghybrid.
Customizing the loader
Pass loaderOptions through to @wyw-in-js/webpack-loader:
// next.config.mjs
import { withWyw } from '@wyw-in-js/nextjs';
export default withWyw(
{
reactStrictMode: true,
},
{
loaderOptions: {
// see /bundlers/webpack for common loader options
},
}
);Disabling vendor prefixing
Stylis adds vendor-prefixed CSS by default. To disable it (and reduce CSS size), pass prefixer: false:
// next.config.mjs
import { withWyw } from '@wyw-in-js/nextjs';
export default withWyw(
{},
{
loaderOptions: {
prefixer: false,
},
turbopackLoaderOptions: {
prefixer: false,
},
}
);Notes
- The plugin emits styles as
*.wyw-in-js.module.cssso imports are allowed from any module. - Add
**/*.wyw-in-js.module.cssto your.gitignoresince these files are generated. - By default, WyW injects
importOverridesforreact/react/jsx-runtimeto avoid resolving Next’s vendored React runtime during eval. Override if you need a different runtime.
Turbopack
Turbopack is the default dev bundler in modern Next.js versions. @wyw-in-js/nextjs configures WyW for Turbopack via
turbopack.rules (webpack-style loaders).
Under the hood, this runs @wyw-in-js/turbopack-loader, which:
- calls
@wyw-in-js/transform, - writes extracted CSS as
*.wyw-in-js.module.cssnext to the source module, - injects
import './*.wyw-in-js.module.css'into the transformed JS/TS output.
To keep WyW class names stable, selectors are wrapped in :global(...) (so Next CSS Modules does not re-hash them), and
@keyframes names are also marked as global.
Turbopack loader options
Use turbopackLoaderOptions to customize @wyw-in-js/turbopack-loader:
// next.config.mjs
import { withWyw } from '@wyw-in-js/nextjs';
export default withWyw(
{
reactStrictMode: true,
},
{
turbopackLoaderOptions: {
// Turbopack requires JSON-serializable options (plain objects/arrays/primitives).
// Pass any function/RegExp-based config via a configFile path.
configFile: './wyw-in-js.config.js',
},
}
);If you already have turbopack.rules for JS/TS in your config, withWyw() merges them and does not override conflicting
rule keys.
Alternatives (3 approaches)
@wyw-in-js/nextjs(official)
- Works in
next dev(Turbopack default) andnext dev --webpack. - Requires generated
*.wyw-in-js.module.cssfiles (add them to.gitignore).
next-with-linaria(community)
- Repo: https://github.com/dlehmhus/next-with-linaria/ (opens in a new tab)
- Not maintained by WyW; may use different CSS injection semantics and extra heuristics.
- Bundler-agnostic extraction (
@wyw-in-js/cli)
- Lets you precompile sources and extract CSS outside of any bundler integration.
- See Bundler-agnostic extraction for details.