Overview
The eslint/universal export provides a browser-compatible version of the ESLint Linter. This build is designed for client-side JavaScript environments where Node.js-specific features are not available.
Import Path
import { Linter } from "eslint/universal" ;
Or using CommonJS:
const { Linter } = require ( "eslint/universal" );
What’s Included
The universal build exports only the Linter class, which is the core linting engine without file system or configuration file dependencies.
Core linting engine that works in browser environments
Differences from Node.js Build
The universal build differs from the main ESLint package:
Feature Main Package Universal Build ESLint class ✅ Yes ❌ No Linter class ✅ Yes ✅ Yes File system access ✅ Yes ❌ No Config file loading ✅ Yes ❌ No RuleTester ✅ Yes ❌ No SourceCode ✅ Yes ❌ No Browser compatible ❌ No ✅ Yes
Usage Example
import { Linter } from "eslint/universal" ;
const linter = new Linter ();
// Define configuration inline
const config = {
rules: {
semi: "error" ,
quotes: [ "error" , "double" ]
}
};
// Lint some code
const code = "const x = 'single quotes'" ;
const messages = linter . verify ( code , config );
console . log ( messages );
// [
// {
// ruleId: 'quotes',
// severity: 2,
// message: "Strings must use doublequote.",
// line: 1,
// column: 11
// }
// ]
Browser Integration
Include the bundle
Use a bundler (webpack, rollup, esbuild) to include eslint/universal in your browser bundle: import { Linter } from "eslint/universal" ;
Create a linter instance
Instantiate the Linter in your browser code: const linter = new Linter ();
Configure rules
Define rules inline (no config file loading): const config = {
languageOptions: {
ecmaVersion: 2022 ,
sourceType: "module"
},
rules: {
"no-unused-vars" : "warn" ,
"no-console" : "error"
}
};
Lint code
Pass code strings directly to the linter: const results = linter . verify ( userCode , config );
displayResults ( results );
Online Code Editor Example
<! DOCTYPE html >
< html >
< head >
< title > ESLint in Browser </ title >
</ head >
< body >
< textarea id = "code" rows = "10" cols = "50" >
const x = 'hello';
console.log(x)
</ textarea >
< button onclick = " lintCode ()" > Lint Code </ button >
< div id = "results" ></ div >
< script type = "module" >
import { Linter } from "eslint/universal" ;
const linter = new Linter ();
window . lintCode = function () {
const code = document . getElementById ( "code" ). value ;
const config = {
rules: {
semi: "error" ,
"no-console" : "warn"
}
};
const messages = linter . verify ( code , config );
const resultsDiv = document . getElementById ( "results" );
resultsDiv . innerHTML = messages . map ( msg =>
`<p>Line ${ msg . line } : ${ msg . message } </p>`
). join ( "" );
};
</ script >
</ body >
</ html >
Use Cases
The universal build is ideal for:
Online code editors (like CodeSandbox, StackBlitz)
Browser-based IDEs
Educational platforms teaching JavaScript
Static site generators with client-side linting
Progressive web apps with code editing features
Limitations
The universal build cannot:
Load configuration files from the file system
Read .eslintignore files
Auto-discover plugins
Access the file system
Use the ESLint class or RuleTester
API Documentation
For detailed Linter API documentation, see:
Linter Class API Complete Linter class reference with all methods and options
Bundle Size Considerations
The universal build is optimized for browser use but still includes all core ESLint functionality:
Core linting engine : AST parsing, rule execution, message generation
Built-in rules : All 294+ ESLint rules are included
Traversal and scope analysis : Full AST traversal and scope management
Consider using tree-shaking and dynamic imports to reduce bundle size if you only need specific rules.
Linter Class Full Linter API reference
Core Concepts Understand how ESLint works
Rule Configuration Configure linting rules
Custom Rules Create custom rules