05 / 06

Discuss css options in vite config — modules, preprocessorOptions, postcss

Vite's CSS configuration is managed through the css object in vite.config.js, providing fine-grained control over CSS Modules, preprocessor options for Sass/Less, and PostCSS integration for advanced transformations

Vite provides comprehensive CSS handling through its css configuration option, offering developers control over three key areas: CSS Modules for locally scoped class names, preprocessor options for Sass/Less/Stylus customization, and PostCSS integration for advanced CSS transformations. These configurations allow teams to implement modern CSS engineering practices while maintaining excellent development experience and build performance .

CSS Modules Configuration
  1. 1

    Vite automatically supports CSS Modules for files ending with .module.css, .module.scss, or .module.less .

  2. 2

    Configure modules through the css.modules object, which accepts all options from postcss-modules .

  3. 3

    Key options include: scopeBehaviour ('global' or 'local'), generateScopedName for custom class naming patterns, hashPrefix for custom hash salts, and globalModulePaths for paths that should always be treated as global .

  4. 4

    Example: css: { modules: { generateScopedName: '[name]_[local]_[hash:base64:5]' } } .

CSS Modules Configuration Example

The preprocessorOptions configuration allows you to pass custom options to CSS preprocessors like Sass, Less, and Stylus. This is particularly useful for injecting global variables, mixins, or functions across all your style files without manually importing them .

Preprocessor Configuration Options
  1. 1

    Sass/SCSS: Use css.preprocessorOptions.scss or css.preprocessorOptions.sass (note the different extensions). The additionalData option is most common for injecting global variables .

  2. 2

    Less: Configure via css.preprocessorOptions.less. Supports modifyVars for theme customization and additionalData for global imports .

  3. 3

    Stylus: Configure via css.preprocessorOptions.stylus with support for define to expose JavaScript variables and include for import paths .

  4. 4

    All preprocessor options support additionalData, which injects content at the beginning of every preprocessed file—ideal for global variables and mixins .

Preprocessor Configuration Examples

Vite includes PostCSS support out of the box, processing all CSS files through configured plugins. You can configure PostCSS either through a dedicated postcss.config.js file or directly in your Vite configuration. PostCSS enables powerful transformations like autoprefixing, CSS nesting, custom properties, and future CSS syntax support .

PostCSS Configuration Options
  1. 1

    Inline configuration: Use css.postcss object in vite.config.js with plugins array and processor options .

  2. 2

    External configuration: Place postcss.config.js in your project root—Vite automatically detects and uses it .

  3. 3

    The plugins array accepts PostCSS plugins (like autoprefixer, postcss-preset-env, cssnano) and supports both string references and inline plugin functions .

  4. 4

    TypeScript note: The plugins array accepts PostCSS.AcceptedPlugin[], which includes both Plugin and PluginCreator types (important for plugins like tailwindcss that export creators) .

  5. 5

    Common plugins include: autoprefixer for vendor prefixes, postcss-import for @import resolution, and cssnano for production minification .

PostCSS Configuration Examples

Beyond the three main categories, Vite offers supplementary CSS configuration options. css.devSourcemap enables source maps during development for easier debugging of transformed CSS . The css.lightningcss option (experimental) replaces PostCSS with Lightning CSS for faster processing . You can also configure css.extract to control whether CSS is extracted during build (default true for production) .

Complete CSS Configuration Example
Difficulty: 5/10
Topics: css modules, preprocessor options, postcss integration

Scenario Questions

0-2 years experience
  1. 1

    You need to add a global SCSS variables file to a Vite project. How would you configure preprocessorOptions in vite.config.ts so every .scss file can use those variables without explicit imports?

  2. 2

    A teammate adds a CSS file with the .module.css extension but the styles aren't being scoped. What could be missing in the Vite config?

  3. 3

    If you enable CSS modules but set css.modules.scopeBehaviour to 'global', what effect does that have on the generated class names?

2-5 years experience
  1. 1

    During a feature rollout you notice PostCSS plugins aren't applied to CSS imported from a node_modules package. Walk me through how you'd debug the Vite config to fix it.

  2. 2

    You need to support both Less and Sass in the same Vite project, but the build fails with a 'cannot find module' error. Which preprocessorOptions would you adjust and why?

  3. 3

    Explain the trade‑offs between using Vite's built‑in CSS modules versus a CSS‑in‑JS solution for a component library you're building.

5-8 years experience
  1. 1

    Our monorepo shares a common PostCSS config across multiple Vite apps. How would you structure the Vite config to avoid duplication while allowing each app to override specific plugins?

  2. 2

    A performance audit shows CSS being duplicated in the final bundle because both CSS modules and global CSS are emitted for the same files. How would you redesign Vite's CSS handling to eliminate the duplication?

  3. 3

    When upgrading Vite from v3 to v5, the css.modules.generateScopedName option changed behavior. How would you ensure backward compatibility for existing component styles across all apps?

8+ years experience
  1. 1

    The company plans to migrate dozens of legacy Webpack projects to Vite. What strategy would you propose for standardizing CSS handling (modules, preprocessors, PostCSS) to minimize friction and maintain consistency across teams?

  2. 2

    You need to design a shared CSS architecture that supports theming, CSS modules, and third‑party UI libraries while keeping build times low. How would you leverage Vite's css options and what governance processes would you put in place?

  3. 3

    Discuss the long‑term maintenance implications of embedding PostCSS plugins directly in each Vite config versus using a central, versioned PostCSS config file. Which approach scales better for a large organization and why?

Follow-up Questions

  • How would you verify that your CSS module naming pattern is being applied in the built files?
  • What impact does the order of PostCSS plugins have on the final CSS?
  • Can you describe a scenario where you’d need to override a preprocessor option for a single component?