Supported bundlers
Nextjs

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/nextjs

Note: 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: tries eval.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 only oxc-resolver; Next's bundler resolver is not called. Mirror bundler-only aliases in oxcOptions.resolver.alias or keep using hybrid.

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.css so imports are allowed from any module.
  • Add **/*.wyw-in-js.module.css to your .gitignore since these files are generated.
  • By default, WyW injects importOverrides for react/react/jsx-runtime to 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.css next 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)

  1. @wyw-in-js/nextjs (official)
  • Works in next dev (Turbopack default) and next dev --webpack.
  • Requires generated *.wyw-in-js.module.css files (add them to .gitignore).
  1. next-with-linaria (community)
  1. Bundler-agnostic extraction (@wyw-in-js/cli)