rhine-lint
v1.9.1
Published
An opinionated linting solution merging ESLint and Prettier with zero config.
Downloads
2,626
Maintainers
Readme
Rhine Lint
Rhine Lint is a "zero-config" modern code linting solution. It deeply integrates ESLint (v9 Flat Config) and Prettier, providing out-of-the-box best practices. No need to manually install dozens of eslint-plugin-* dependencies or write hundreds of lines of configuration. Just one dependency, one command, and you get top-tier code quality protection.
Features
- Zero Config: Provides best practice configurations for TypeScript, React, and Next.js by default. Ready to use upon installation.
- Unified Toolchain: A single
rlcommand executes both code linting (Lint) and code formatting (Format). - Full Stack Support:
- JavaScript / TypeScript: Complete type checking support.
- Frontend: React (v18/v19), React Hooks, JSX A11y.
- Frameworks: Next.js (Pages & App Router).
- Styles: CSS, SCSS format support.
- Others: JSON, Markdown support.
- Smart Config Generation: Dynamically generates configuration files at runtime, keeping your project root clean from ESLint/Prettier config files.
- Extensible: Supports
rhine-lint.config.tsfor rule overrides or deep customization.
Installation
Install as a dev dependency in your project:
# Bun (Recommended)
bun add -D rhine-lint
# npm
npm install --save-dev rhine-lint
# pnpm
pnpm add -D rhine-lint
# yarn
yarn add -D rhine-lintQuick Start
Initialize Configuration
The quickest way to get started is using the rl init command:
rl initThis interactive wizard will:
- Detect project features - Automatically scans
package.jsonfor TypeScript, React, Next.js, Sass - Configure options - Prompts you to confirm or customize:
- Project level (normal/react/next)
- TypeScript support
- Project-based type checking
- Generate config file - Creates
rhine-lint.config.ts(or.jsfor non-TypeScript projects) - Add npm scripts - Optionally adds
lintandlint:fixscripts topackage.json - Pre-generate configs - Generates ESLint and Prettier configurations for faster first run
Example output:
+------------------------------------------------+
| |
| Rhine Lint |
| Zero-config linting solution |
| |
+------------------------------------------------+
[1/4] Detecting project features...
• TypeScript: ✓
• React: ✓
• Next.js: ✗
• Sass/SCSS: ✗
• Recommended level: React
--------------------------------------------------
[2/4] Configure options
? Use detected level react? [Y/N]
? Enable TypeScript support? [Y/N]
? Enable project-based type checking? [Y/N]
? Add lint and lint:fix scripts to package.json? [Y/N]
--------------------------------------------------
[3/4] Generating configuration files...
RL Created rhine-lint.config.ts
RL Added lint and lint:fix scripts to package.json
RL Generated eslint.config.mjs
RL Generated prettier.config.mjs
--------------------------------------------------
[4/4] Configuration complete!
RL Configuration summary:
• Level: react
• TypeScript: enabled
• Project Type Check: enabled
• Scripts added: enabled
RL Run rl to lint your project.
RL Run rl --fix to auto-fix issues.CLI Usage
After installation, you can use the rl command directly:
# Check version
rl --version
# Check all files in current directory (default: lint + check format)
rl
# Auto-fix all fixable code style issues
rl --fix
# Check specific files or directories
rl src/components
# Specify project type (override auto-detection or default)
rl --level nextRecommended Configuration
Add scripts to package.json for daily use:
{
"scripts": {
"lint": "rl",
"lint:fix": "rl --fix"
}
}Configuration
Although Rhine Lint is zero-config, it also supports deep customization through configuration files. It automatically detects rhine-lint.config.{ts,js,mjs,json} in the project root directory.
Configuration File Example (rhine-lint.config.ts)
import { type Config } from 'rhine-lint';
export default {
// Specify project level: 'normal' | 'react' | 'next'
// Default is 'react'
level: 'next',
// Enable TypeScript support (optional)
// true: Enable TypeScript rules (TS, TSX files)
// false: JavaScript mode (JS, JSX files)
// Default is true
typescript: true,
// Enable fix mode by default (optional)
fix: false,
// Custom cache directory (optional)
// cacheDir: './.cache/rhine-lint',
// Enable project-based type checking (optional)
// When enabled, uses projectService and strictTypeChecked rules
// Slower but more accurate type-aware linting
// Set to false to disable for faster single-file processing
// Default is true
projectTypeCheck: true,
// Specify tsconfig file path (optional)
// Used for TypeScript type checking and import path resolution
// Can be absolute or relative to project root
// Default is './tsconfig.json'
tsconfig: './tsconfig.app.json',
// Additional ignore patterns (optional)
// These patterns are merged with .gitignore and default ignores
ignores: ['temp', 'generated', '*.test.ts'],
// ESLint specific configuration
eslint: {
// Enable ESLint (default is true)
// Set to false to disable ESLint checking
enable: true,
// Custom ESLint rules (Flat Config format)
// These configurations are merged with defaults
config: [
{
rules: {
'no-console': 'warn',
'react/no-unknown-property': 'off'
}
}
// ...
]
},
// Prettier specific configuration
prettier: {
// Enable Prettier (default is true)
// Set to false to disable Prettier format checking
enable: true,
config: {
printWidth: 100,
semi: true,
// ...
}
}
} as Config;Arguments
CLI arguments take priority over configuration file:
--fix: Auto-fix errors.--config <path>: Specify configuration file path.--level <level>: Force project level (normal,react,next).--no-typescript: Disable TypeScript support, use JavaScript mode.--no-project-type-check: Disable project-based type checking (can speed up single-file processing).--tsconfig <path>: Specify tsconfig file path (for type checking and import resolution).--ignore-file <path>: Specify gitignore-style ignore file (can be used multiple times, e.g.--ignore-file .gitignore --ignore-file .eslintignore).--ignore <pattern>: Add ignore pattern (can be used multiple times, e.g.--ignore dist --ignore coverage).--no-ignore: Force disable all ignore rules (including ignoreFiles and ignores).--only-eslint: Only run ESLint, skip Prettier.--only-prettier: Only run Prettier, skip ESLint.--no-time: Disable elapsed time display (enabled by default).--debug: Print debug information (including generated configs, ignore lists, etc.).--cache-dir <dir>: Specify cache directory (default usesnode_modules/.cache/rhine-lint).
TypeScript Configuration Options
projectTypeCheck
Controls whether to enable project-based TypeScript type checking:
- When enabled (default): Uses
projectServiceandstrictTypeCheckedrules, providing more accurate type-aware linting, but slower. - When disabled: Uses a lighter ruleset, suitable for fast single-file checks or CI environments.
# Disable project type checking (CLI)
rl --no-project-type-check
# Set in configuration file
# rhine-lint.config.ts
export default {
projectTypeCheck: false
}tsconfig
Specify the tsconfig file for TypeScript type checking and import path resolution:
# Specify tsconfig path (CLI)
rl --tsconfig ./tsconfig.app.json
# Set in configuration file
# rhine-lint.config.ts
export default {
tsconfig: './tsconfig.app.json'
}Default is ./tsconfig.json. If your project uses different tsconfig files (like tsconfig.app.json, tsconfig.node.json, etc.), you can specify them via this option.
Ignore Patterns
Rhine Lint provides flexible file ignore mechanisms with multiple configuration methods.
Default Ignores
The following directories are always ignored (no configuration needed):
node_modules,dist,.next,.git,.output,.nuxt,coverage,.cache
The following files are ignored by default (can be overridden by configuration):
package-lock.json,yarn.lock,pnpm-lock.yaml,bun.lock
ignoreFiles
Rhine Lint automatically parses .gitignore-style files, converting patterns to ESLint ignore rules.
Default value: ['./.gitignore']
# CLI: Specify ignore files (overrides default, supports multiple uses)
rl --ignore-file .gitignore --ignore-file .eslintignore// rhine-lint.config.ts
export default {
// Specify list of ignore files to read
ignoreFiles: ['./.gitignore', './.eslintignore']
}ignores
Directly specify file or directory patterns to ignore.
Default value: ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock']
# CLI: Add ignore patterns (merged with config file, supports multiple uses)
rl --ignore temp --ignore generated --ignore "*.test.ts"// rhine-lint.config.ts
export default {
// Specify file/directory patterns to ignore
ignores: ['temp', 'generated', '*.test.ts']
}Disable Ignores --no-ignore
# Disable all ignore rules (including ignoreFiles and ignores)
rl --no-ignoreIgnore Pattern Priority
--no-ignoredisables all ignore processing- Otherwise, merged in the following order:
- Default always-ignored directories (always active)
- Parsed results from files in
ignoreFiles ignorespattern list
Priority rules:
--ignore-file: When specified via CLI, overridesignoreFilesin config file--ignore: When specified via CLI, overridesignoresin config file- Final results of both
ignoreFilesandignorestake effect (merged)
Cache Directory
Rhine Lint needs a directory to store dynamically generated "Virtual Config" files at runtime. These files are temporary and typically don't require user attention. Cache directory resolution priority (high to low):
- CLI argument: Explicitly specified via
--cache-dir <path>in command line. - Config file:
cacheDirfield inrhine-lint.config.ts. - Default location (standard):
node_modules/.cache/rhine-lint(if project hasnode_modulesdirectory). - Fallback location:
.cache/rhine-lint(created in project root ifnode_modulesis not found).
Note: If your project triggers case 4 (fallback location), it's recommended to add
.cache/to your.gitignoreto prevent these temporary files from being committed to version control. Normally, Rhine Lint attempts to clean up these temporary files after execution, but keeping them in.gitignoreis a safer practice.
Project Levels
Rhine Lint loads different rulesets based on level and typescript parameters.
Auto Detection
When level is not specified, Rhine Lint automatically analyzes dependencies and devDependencies in package.json:
- Detected
nextdependency → useslevel: 'next' - Detected
reactdependency → useslevel: 'react' - Cannot detect → warns and uses
level: 'normal'
Level Options
normal: Basic project. Only includes standard rules and Prettier.react: React frontend project. Includes allnormallevel rules, plusReact,React Hooks,JSXrelated rules.next: Next.js project. Includes allreactlevel rules, plus@next/eslint-plugin-nextCore Web Vitals and other rules.
TypeScript Options
typescript: true(default): Enables TypeScript rules, supports.ts,.tsxfiles, includes type checking rules.typescript: false: JavaScript mode, supports.js,.jsxfiles, no type checking.
Combination Examples
| level | typescript | Description |
|-------|------------|-------------|
| normal | true | TypeScript basic project |
| normal | false | JavaScript basic project |
| react | true | TypeScript + React project |
| react | false | JavaScript + React project |
| next | true | TypeScript + React + Next.js project |
| next | false | JavaScript + React + Next.js project |
Trigger Fix when Save
VS Code (Cursor, Antigravity, ...)
Use the Run on Save extension to trigger auto-fix on save.
- Install extension:
emeraldwalk.RunOnSave - Add to
.vscode/settings.json:
{
"emeraldwalk.runonsave": {
"commands": [
{
"match": "\\.(js|jsx|ts|tsx|css|scss|md|json)$",
"cmd": "${workspaceFolder}/node_modules/.bin/rl \"${file}\" --fix --only-prettier"
},
{
"match": "\\.(js|jsx|ts|tsx)$",
"cmd": "${workspaceFolder}/node_modules/.bin/rl \"${file}\" --fix --no-project-type-check"
}
]
}
}- Disable VS Code's built-in formatting to avoid conflicts:
{
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {}
}JetBrains IDE (WebStorm, IDEA, PyCharm, ...)
Use File Watchers to trigger auto-fix on save. You need to create a file watcher to trigger Prettier commands.
Step 0: Preparation
- Make sure rhine-lint is installed and you have run any
rlcommand at least once (to ensure ESLint and Prettier config files are generated to the cache directory). If not, runrl initto initialize and generate configs.
Step 1: Configure Prettier Fix on Save
- Open
Settings→Tools→File Watchers - Click
+→ Select<custom>template - Enter the following settings:
| Setting | Value |
|---------|-------|
| Name | Rhine Lint Prettier |
| File type | Any |
| Program | $ProjectFileDir$/node_modules/.bin/rl |
| Arguments | "$FilePath$" --fix --only-prettier |
| Output paths to refresh | $FilePath$ |
| Working directory | $ProjectFileDir$ |
- In
Advanced Options, uncheckAuto-save edited files to trigger the watcher. (This prevents overly frequent auto-updates during development; you can manually trigger with Ctrl+S) - Click OK to confirm the template, then click Apply to enable.
Step 2: Configure ESLint Fix on Save
- Open
Languages & Frameworks→JavaScript→Code Quality Tools→ESLint - Select Manual ESLint configuration
- In ESLint Package, select path
{project-path}\node_modules\eslint - In Working directories, select your project path
- In Configuration File, select path
{project-path}\node_modules\.cache\rhine-lint\eslint.config.mjs - Check
Run eslint --fix on saveat the bottom
Implementation Insights
This chapter details the internal working mechanism of Rhine Lint. If you want to contribute to this project or deeply customize functionality, you can get started quickly with the following content.
Rhine Lint's core essence is a Configuration Factory and Execution Orchestrator. It doesn't rewrite a Linter but stands on the shoulders of giants (ESLint & Prettier), solving configuration complexity through a thin wrapper.
1. Core Architecture
The entire execution flow can be divided into three phases: Init -> Generate -> Execute.
graph TD
CLI[src/cli.ts] -->|Parse Args| ConfigMgr[src/core/config.ts]
subgraph Configuration Phase
ConfigMgr -->|1. Read User Config| UserConfig[rhine-lint.config.ts]
ConfigMgr -->|2. Read Built-in Templates| Assets[src/assets/*.js]
ConfigMgr -->|3. Merge & Compile| VirtualConfig[Generate Temp Config\n.cache/rhine-lint/*.mjs]
end
subgraph Execution Phase
CLI --> Executor[src/core/runner.ts]
Executor -->|Spawn Process| ESLint[(ESLint Binary)]
Executor -->|Spawn Process| Prettier[(Prettier Binary)]
ESLint -.->|Read| VirtualConfig
Prettier -.->|Read| VirtualConfig
end
ESLint -->|Output| Formatter[Result Cleaning & Display]
Prettier -->|Output| Formatter2. Module Deep Dive
CLI Entry (src/cli.ts)
- Responsibility: The program's entry point.
- Implementation: Uses the
caclibrary to handle command-line arguments (like--fix,--level).
CLI Options Definition
cli
.command("[...files]", "Lint files")
.option("--fix", "Fix lint errors")
.option("--config <path>", "Path to config file")
.option("--level <level>", "Project level (normal, react, next)")
.option("--no-typescript", "Disable TypeScript support (JavaScript only mode)")
.option("--no-project-type-check", "Disable project-based type checking")
.option("--tsconfig <path>", "Path to tsconfig file")
.option("--ignore-file [path]", "Add gitignore-style file (can be used multiple times)")
.option("--ignore [pattern]", "Add ignore pattern (can be used multiple times)")
.option("--no-ignore", "Disable all ignore rules")
.option("--cache-dir <dir>", "Custom cache directory")
.option("--no-time", "Disable elapsed time display")
.option("--only-eslint", "Only run ESLint (skip Prettier)")
.option("--only-prettier", "Only run Prettier (skip ESLint)")
.option("--debug", "Enable debug mode")Key Logic
// --ignore parameter handling (supports multiple calls)
// cac automatically collects multiple --ignore into an array
// --no-ignore sets options.ignore = false
const noIgnore = options.ignore === false;
let ignorePatterns: string[] = [];
if (!noIgnore && options.ignore && options.ignore !== true) {
ignorePatterns = Array.isArray(options.ignore)
? options.ignore.filter((p: unknown) => typeof p === 'string')
: [options.ignore];
}
// --ignore-file parameter handling
let ignoreFiles: string[] = [];
if (!noIgnore && options.ignoreFile && options.ignoreFile !== true) {
ignoreFiles = Array.isArray(options.ignoreFile)
? options.ignoreFile.filter((p: unknown) => typeof p === 'string')
: [options.ignoreFile];
}- Logic:
- It doesn't call the ESLint API directly, but prepares environment paths.
- Calls
generateTempConfigto prepare configuration files. - Calls
runEslintandrunPrettierto start subprocesses. - Finally determines whether the
rlcommand succeeds or fails based on subprocess exit codes.
Configuration Generator (src/core/config.ts) - Core
This is the most complex part of the project. To achieve "zero-config" without polluting the user's directory, we adopt a Virtual Configuration strategy.
Function Signature
export async function generateTempConfig(
cwd: string, // Project root directory
userConfigResult: { config: Config, path?: string }, // User config
cliLevel?: string, // --level argument
cliCacheDir?: string, // --cache-dir argument
debug?: boolean, // --debug argument
cliProjectTypeCheck?: boolean, // --no-project-type-check
cliTsconfig?: string, // --tsconfig argument
cliIgnorePatterns: string[] = [], // --ignore argument (array)
noIgnore: boolean = false, // --no-ignore argument
cliIgnoreFiles: string[] = [] // --ignore-file argument (array)
): Promise<{ eslintPath: string; prettierPath: string; cachePath: string }>Core Flow
Parameter Priority Handling: CLI arguments > Config file > Defaults
const projectTypeCheck = cliProjectTypeCheck ?? userConfigResult.config.projectTypeCheck ?? true; const tsconfigPath = cliTsconfig ?? userConfigResult.config.tsconfig; // ignoreFiles: CLI overrides config overrides default const resolvedIgnoreFiles = cliIgnoreFiles.length > 0 ? cliIgnoreFiles : (userConfigResult.config.ignoreFiles ?? DEFAULT_IGNORE_FILES); // ignores: CLI overrides config overrides default const resolvedIgnores = cliIgnorePatterns.length > 0 ? cliIgnorePatterns : (configIgnores.length > 0 ? configIgnores : DEFAULT_IGNORES); // Final ignoreFiles and ignores both take effectSmart Caching (SHA-256 Fingerprint):
const hash = createHash("sha256"); hash.update(pkg.version || "0.0.0"); hash.update(cliLevel || "default"); hash.update(projectTypeCheck ? "ptc-on" : "ptc-off"); hash.update(tsconfigPath || "default-tsconfig"); hash.update(resolvedIgnoreFiles.join(",") || "no-ignore-files"); hash.update(resolvedIgnores.join(",") || "no-ignores"); hash.update(noIgnore ? "no-ignore" : "with-ignore"); // + user config file content + each ignore file contentIgnore Pattern Processing:
- If
--no-ignore, skip all ignore processing - Otherwise:
- Add default always-ignored directories
- Parse all files in
ignoreFiles - Add
ignorespattern list
- Pattern normalization: Automatically adds
**/prefix and/**suffix
- If
Generate Virtual Config: Dynamically generates
eslint.config.mjscontent, including:- Ignore pattern array
- User config loading logic
- Rules based on level
- Dynamic Generation: We don't rely on
.eslintrcin the user's project. Instead, at runtime, we generate a realeslint.config.mjsinnode_modules/.cache/rhine-lint/. - TypeScript Config Compilation: If user's config file is detected as
.tsformat:- Automatically calls the built-in TypeScript compiler to transpile it to
.mjsmodule. - The transpiled file is saved in the cache directory (like
.cache/rhine-lint/rhine-lint.user-config.mjs). - The generated ESLint config points to this compiled JS file, solving the limitation that Node.js cannot natively load TS files.
- Automatically calls the built-in TypeScript compiler to transpile it to
- Smart Caching: To improve performance (especially for IDE save auto-fix), we implement a fingerprint-based caching mechanism:
- Fingerprint Calculation: Before each run, calculates a SHA-256 hash including:
package.jsonversion + CLI arguments + user config file content +.gitignorestatus. - Fast Hit: If fingerprint matches the cached
metadata.json, completely skips heavy transpilation, merging, and file write operations, directly reusing the previous config.
- Fingerprint Calculation: Before each run, calculates a SHA-256 hash including:
- JIT Loading: Besides static compilation above, we use
jitifor some module loading to ensure compatibility. - Key Point: This design allows dependencies inside
rhine-lint(likeeslint-plugin-react) to be resolved correctly without users explicitly installing them.
Rule Assets (src/assets/eslint.config.js)
This stores the "source" of Lint rules. It's a Factory Function that exports the createConfig(options) function.
OPTIONS Configuration
const OPTIONS = {
ENABLE_SCRIPT: true, // Enable TS/JS file processing
ENABLE_TYPE_CHECKED: true, // Enable type checking rules
ENABLE_PROJECT_BASE_TYPE_CHECKED: true, // Enable project-level type checking (projectService)
ENABLE_FRONTEND: true, // Enable React/JSX rules
ENABLE_NEXT: false, // Enable Next.js rules
ENABLE_MARKDOWN: true, // Enable Markdown rules
ENABLE_JSON: true, // Enable JSON rules
ENABLE_STYLESHEET: true, // Enable CSS rules
IGNORE_PRETTIER: true, // Disable rules conflicting with Prettier
TSCONFIG_PATH: './tsconfig.json', // tsconfig file path
...overrides // Runtime overrides
}Config Block Assembly
return [
...globalConfig, // Global ignore config
...scriptConfig, // TS/JS base rules + import-x + unused-imports
...frontendConfig, // React/Next.js rules (conditionally loaded by level)
...cssConfig, // CSS rules
...markdownConfig, // Markdown rules
...jsonConfig, // JSON/JSONC rules
...prettierConfig, // eslint-config-prettier (disable conflicting rules)
...customConfig, // Custom rule overrides
]- Flat Config: Uses ESLint v9's Flat Config array format.
- On-demand Loading: Based on the passed
options.level(likefrontendornextjs), it dynamicallypushes different config blocks to the array. For example, only innextjsmode are@next/eslint-plugin-nextrelated rules loaded. - Plugin Integration: All plugins (
react,import-x,unused-imports, etc.) are imported and configured here.
Execution Engine (src/core/runner.ts)
Core Functions
// General command execution
async function runCommandWithOutput(
command: string,
args: string[],
cwd: string
): Promise<{ output: string, code: number }>
// ESLint execution
async function runEslint(
cwd: string,
configPath: string, // Generated virtual config path
fix: boolean,
files: string[]
): Promise<string | null> // Returns error summary or null
// Prettier execution
async function runPrettier(
cwd: string,
configPath: string,
fix: boolean,
files: string[]
): Promise<string | null>Binary Resolution Strategy
function resolveBin(pkgName: string, binPathRelative: string): string {
// 1. Try require.resolve (fastest)
// 2. Fallback: traverse directories to find package.json
// 3. Fallback: use system PATH
}- Process Isolation: We use Node.js's
child_process.spawnto calleslintandprettierexecutables. - Why Not Use API?:
- Using API (like
new ESLint()) may cause singleton conflicts or behave inconsistently with CLI in some edge cases. - Calling CLI via spawn ensures maximum compatibility and leverages multi-core CPUs to run Lint and Prettier in parallel.
- Using API (like
- Output Cleaning: Native ESLint output can be too verbose for regular users. At this layer, we capture stdout/stderr, remove ANSI noise, and extract the key "X problems found" summary to give users the most intuitive feedback.
3. Type Definitions (src/config.ts)
export type Config = {
/**
* Project level, determines which rules to enable
* Each level includes all rules from the previous level:
* - 'normal': Base rules (JS or TS based on typescript option)
* - 'react': Normal + React/JSX/Hooks rules
* - 'next': React + Next.js rules
* @default 'react'
*/
level?: 'normal' | 'react' | 'next',
/**
* Enable TypeScript support and type-aware rules
* - true: Enable TypeScript rules (TS, TSX files)
* - false: JavaScript mode (JS, JSX files)
* @default true
*/
typescript?: boolean,
/**
* Directory to store generated virtual config files and cache metadata
* @default 'node_modules/.cache/rhine-lint' or '.cache/rhine-lint'
*/
cacheDir?: string,
/**
* Auto-fix lint errors and format issues
* @default false
*/
fix?: boolean,
/**
* Enable elapsed time output for each phase
* @default true
*/
time?: boolean,
/**
* Enable project-based TypeScript type checking
* Enables projectService and strictTypeChecked rules
* Slower but more accurate type-aware linting
* @default true
*/
projectTypeCheck?: boolean,
/**
* tsconfig file path
* @default './tsconfig.json' or './tsconfig.app.json'
*/
tsconfig?: string,
/**
* List of gitignore-style ignore files
* @default ['./.gitignore']
*/
ignoreFiles?: string[],
/**
* List of ignore patterns
* @default ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock']
*/
ignores?: string[],
/** @deprecated Use ignores instead */
ignore?: string[],
eslint?: {
/** Enable ESLint @default true */
enable?: boolean,
/** ESLint Flat Config array */
config?: Linter.Config[],
/** Override mode (true: completely override built-in config) */
overlay?: boolean,
},
prettier?: {
/** Enable Prettier @default true */
enable?: boolean,
/** Prettier config object */
config?: PrettierConfig,
/** Override mode (true: completely override built-in config) */
overlay?: boolean,
}
}4. Development Guide
If you want to add new features to Rhine Lint, follow these paths:
Adding a New ESLint Plugin
- Install Dependency: Install the plugin in the
rhine-lintproject, e.g.,bun add eslint-plugin-vue. - Register Plugin: Modify
src/assets/eslint.config.js.- Import the plugin.
- In the
createConfigfunction, add a new logic branch (e.g.,if (OPTIONS.ENABLE_VUE) { ... }). - Define
pluginsandrules.
- Update Types: Add the new Scope toggle in the
Configtype definition insrc/config.ts. - Test: Create a Vue file in the
playgrounddirectory, runbun start --level vue(assuming you added vue level) to verify.
Debugging
This project is written entirely in TypeScript.
- Build:
bun run build(compiles withtsctodist/). - Link: Run
npm linkin the project root, thennpm link rhine-lintin the test project. - Watch: You can also use
bun run dev(if configured) or manually watch file changes.
5. Directory Structure
rhine-lint/
├── src/
│ ├── assets/ # Default config file templates (ESLint/Prettier)
│ ├── core/
│ │ ├── config.ts # Config loading and temp file generation logic
│ │ └── runner.ts # Subprocess executor
│ ├── utils/ # Utility functions (Logger, etc.)
│ ├── cli.ts # Command-line entry
│ ├── config.ts # Type definitions
│ └── index.ts # API exports for users
├── scripts/ # Build scripts
└── package.jsonLicense
MIT © RhineAI
