CSS Browser Support Linter
Doiuse is a JavaScript library and CLI tool that lints CSS code for browser support issues by comparing features used in the CSS against the Can I use database. It helps developers identify CSS properties and values that are not supported by their target browser list, preventing unexpected rendering problems. The current stable version is 6.0.6, released in early 2024, with maintenance releases occurring as needed to fix bugs and update feature definitions. It integrates well into build pipelines, notably as a PostCSS plugin or a transform stream. A key differentiator is its direct reliance on the `caniuse` database for accurate, up-to-date compatibility data, allowing for highly customizable browser targets using `browserslist` syntax. While it focuses on identifying unsupported features, its "naive" detection approach means it primarily checks for direct property/value matches rather than complex runtime interpretation, offering a fast and focused linting experience.
Common errors
-
Error: Cannot find module 'doiuse/lib/DoIUse.js'
cause Attempting to import the `DoIUse` class incorrectly, often from the main package entry point or with a wrong path.fixEnsure you are importing from the correct path: `import DoIUse from 'doiuse/lib/DoIUse.js';` for ESM or `const DoIUse = require('doiuse/lib/DoIUse');` for CommonJS. -
SyntaxError: Unexpected token 'export' (for ESM usage in CJS context) OR require() of ES Module (for CJS usage in ESM context)
cause Mixing ESM `import` statements with CommonJS `require()` or vice-versa, or running a module type in an incompatible environment.fixFor ESM, ensure your project is configured with `"type": "module"` in `package.json` and use `import` statements. For CommonJS, use `require()` and ensure files are `.js` or `.cjs`. Doiuse v6.x is largely ESM-first, so adjust your imports accordingly. -
TypeError: doiuse is not a function
cause This typically happens when trying to call `doiuse` directly after a `require('doiuse')` which returns the CLI function, not the PostCSS plugin or stream constructor.fixFor programmatic use, ensure you are importing the specific PostCSS plugin or stream entry point: `const doiusePlugin = require('doiuse/lib/DoIUse');` or `const doiuseStream = require('doiuse/stream');`.
Warnings
- breaking Version 6.0.0 of `doiuse` dropped support for Node.js v12 and v14. Projects must upgrade to Node.js v16 or higher.
- breaking Older versions of `doiuse` (prior to v4.3.0) dropped support for Node.js versions older than 10.x and 4.x respectively. Ensure your Node.js version meets the minimum requirements for your `doiuse` version.
- gotcha The `doiuse` package uses specific import paths for its PostCSS plugin and stream API (e.g., `doiuse/lib/DoIUse.js`, `doiuse/stream`). Direct `import DoIUse from 'doiuse'` or `require('doiuse')` will not work for programmatic usage as intended for the plugin or stream.
- gotcha The feature detection in `doiuse` is described as 'quite naive,' primarily relying on regex/substring matches of property and value names. It may not catch all nuanced browser compatibility issues, especially those involving complex CSS interactions or JavaScript polyfills.
Install
-
npm install doiuse -
yarn add doiuse -
pnpm add doiuse
Imports
- DoIUse
import { DoIUse } from 'doiuse';import DoIUse from 'doiuse/lib/DoIUse.js';
- doiuse
import { doiuse } from 'doiuse';import doiuse from 'doiuse/stream';
- require('doiuse')
const { DoIUse } = require('doiuse');const doiuseCli = require('doiuse'); - DoIUse (CommonJS)
const DoIUse = require('doiuse');const DoIUse = require('doiuse/lib/DoIUse');
Quickstart
import postcss from 'postcss';
import DoIUse from 'doiuse/lib/DoIUse.js';
const cssInput = `
a {
background-size: cover;
display: flex; /* flexbox support */
user-select: none;
scroll-snap-align: start;
}
.gradient {
background-image: conic-gradient(white, black);
}
`;
postcss(new DoIUse({
browsers: ['last 2 chrome versions', 'ie 11'], // Target specific browsers
ignore: ['flexbox', 'user-select-none'], // Optional: ignore specific features by 'caniuse' ID
ignoreFiles: ['**/node_modules/**'], // Optional: ignore files matching these globs
onFeatureUsage: (usageInfo) => {
// Log detailed information about each unsupported feature found
console.log(`[doiuse] ${usageInfo.message} in ${usageInfo.feature} for ${usageInfo.browsers.join(', ')} at ${usageInfo.source.start.line}:${usageInfo.source.start.column}`);
}
})).process(cssInput, { from: 'example.css' })
.then(result => {
console.log('\nProcessed CSS (no changes made by doiuse):\n', result.css);
})
.catch(error => {
console.error('PostCSS processing failed:', error);
});