High-performance JavaScript and TypeScript linter written in Rust, designed as part of the Oxc (Oxidation Compiler) suite of tools
Oxlint provides experimental JavaScript bindings through NAPI (Node.js API) for advanced integrations and custom linting workflows. This API allows developers to build JavaScript plugins and integrate oxlint directly into Node.js applications.
The npm package includes pre-built native binaries for:
win32-x64 - Windows x64win32-arm64 - Windows ARM64darwin-x64 - macOS Inteldarwin-arm64 - macOS Apple Siliconlinux-x64-gnu - Linux x64 (GNU libc)linux-arm64-gnu - Linux ARM64 (GNU libc)linux-x64-musl - Linux x64 (musl libc)linux-arm64-musl - Linux ARM64 (musl libc)The primary API for JavaScript plugin integration.
/**
* Main lint function for JavaScript plugins (experimental)
* Only available on 64-bit little-endian platforms
*
* @param loadPlugin - Callback to load plugin from path
* @param lintFile - Callback to process lint results
* @returns Promise resolving to success status
*/
function lint(
loadPlugin: (path: string) => Promise<string>,
lintFile: (filePath: string, bufferId: number, buffer: Uint8Array | null, ruleIds: number[]) => string
): Promise<boolean>;/**
* Plugin loading callback
* @param path - Path to the plugin file
* @returns Promise resolving to plugin content
*/
type LoadPluginCallback = (path: string) => Promise<string>;
/**
* File linting callback
* @param filePath - Path to file being linted
* @param bufferId - Internal buffer identifier
* @param buffer - File content buffer (null for deleted files)
* @param ruleIds - Array of rule IDs to apply
* @returns Serialized lint results
*/
type LintFileCallback = (
filePath: string,
bufferId: number,
buffer: Uint8Array | null,
ruleIds: number[]
) => string;import { lint } from "oxlint";
async function customLintWorkflow() {
// Plugin loader - loads JavaScript plugins from filesystem
const loadPlugin = async (pluginPath: string): Promise<string> => {
const fs = await import('fs/promises');
return await fs.readFile(pluginPath, 'utf-8');
};
// File processor - handles lint results for each file
const lintFile = (
filePath: string,
bufferId: number,
buffer: Uint8Array | null,
ruleIds: number[]
): string => {
if (!buffer) {
return JSON.stringify({ deleted: true, filePath });
}
// Process file content and return results
const content = new TextDecoder().decode(buffer);
const results = {
filePath,
bufferId,
contentLength: content.length,
appliedRules: ruleIds,
processed: true
};
return JSON.stringify(results);
};
try {
const success = await lint(loadPlugin, lintFile);
console.log(`Linting ${success ? 'succeeded' : 'failed'}`);
} catch (error) {
console.error('Linting error:', error);
}
}// Custom plugin structure
interface CustomPlugin {
name: string;
version: string;
rules: Record<string, any>;
}
const loadPlugin = async (pluginPath: string): Promise<string> => {
// Load plugin configuration
const pluginModule = await import(pluginPath);
const plugin: CustomPlugin = {
name: pluginModule.default.name || 'custom-plugin',
version: pluginModule.default.version || '1.0.0',
rules: pluginModule.default.rules || {}
};
return JSON.stringify(plugin);
};import { platform, arch } from 'os';
function isJsPluginSupported(): boolean {
// JS plugins only work on 64-bit little-endian platforms
const supportedPlatforms = [
'win32-x64', 'win32-arm64',
'linux-x64', 'linux-arm64',
'darwin-x64', 'darwin-arm64'
];
const currentPlatform = `${platform()}-${arch()}`;
return supportedPlatforms.includes(currentPlatform) &&
process.arch === 'x64' || process.arch === 'arm64';
}
// Check before using JS plugins
if (isJsPluginSupported()) {
// Use lint() function
} else {
console.warn('JavaScript plugins not supported on this platform');
}import { lint } from "oxlint";
const loadPlugin = async (path: string): Promise<string> => {
try {
// Plugin loading logic
return await loadPluginContent(path);
} catch (error) {
throw new Error(`Failed to load plugin from ${path}: ${error.message}`);
}
};
const lintFile = (filePath: string, bufferId: number, buffer: Uint8Array | null, ruleIds: number[]): string => {
try {
if (!buffer) {
return JSON.stringify({
error: 'File not found or deleted',
filePath
});
}
// File processing logic
return JSON.stringify({ success: true, filePath });
} catch (error) {
return JSON.stringify({
error: error.message,
filePath,
bufferId
});
}
};
// Main error handling
try {
const result = await lint(loadPlugin, lintFile);
if (!result) {
console.error('Linting completed with errors');
}
} catch (error) {
if (error.message?.includes('not supported')) {
console.error('JS plugins not supported on this platform');
} else {
console.error('Unexpected linting error:', error);
}
}# Install via npm (includes platform-specific binaries)
npm install oxlint
# Verify installation
npx oxlint --versionThe npm package also provides direct binary access:
# Access binary directly
./node_modules/.bin/oxlint [options]
# Or through npm scripts
{
"scripts": {
"lint": "oxlint src/",
"lint:fix": "oxlint --fix src/"
}
}import { lint } from "oxlint";
import { execSync } from "child_process";
async function ciLintProcess() {
// Custom plugin for CI-specific rules
const loadPlugin = async (path: string) => {
return JSON.stringify({
name: "ci-plugin",
rules: {
"no-console-in-production": "error",
"require-file-headers": "warn"
}
});
};
const lintFile = (filePath: string, bufferId: number, buffer: Uint8Array | null, ruleIds: number[]) => {
// CI-specific file processing
const result = {
file: filePath,
ciCheck: true,
timestamp: new Date().toISOString()
};
return JSON.stringify(result);
};
const success = await lint(loadPlugin, lintFile);
// Set CI exit code
process.exit(success ? 0 : 1);
}This experimental API provides powerful integration capabilities for advanced use cases while maintaining the performance benefits of the core Rust implementation.
Install with Tessl CLI
npx tessl i tessl/npm-oxlint