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.
- 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.
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-lintThe 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.
After installation, you can use the rl command directly:
# Initialize configuration interactively
rl init
# Generate config files (force regenerate, ignore cache)
rl config
# 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 nextAdd scripts to package.json for daily use:
{
"scripts": {
"lint": "rl",
"lint:fix": "rl --fix"
}
}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.
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,
// Copy generated config to project root for IDE integration (optional)
// Useful when your IDE cannot detect configs in cache directory
copyConfigFileTo: './eslint.config.mjs',
// 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,
// Copy generated config to project root for IDE integration (optional)
copyConfigFileTo: './prettier.config.mjs',
config: {
printWidth: 100,
semi: true,
// ...
}
}
} as Config;CLI arguments take priority over configuration file:
--fix: Auto-fix errors.--no-fix: Disable auto-fix (overridesfix: truein config file).--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).
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
}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.
Rhine Lint provides flexible file ignore mechanisms with multiple configuration methods.
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
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']
}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 all ignore rules (including ignoreFiles and ignores)
rl --no-ignore--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)
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.
Rhine Lint loads different rulesets based on level and typescript parameters.
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'
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: true(default): Enables TypeScript rules, supports.ts,.tsxfiles, includes type checking rules.typescript: false: JavaScript mode, supports.js,.jsxfiles, no type checking.
| 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 |
- Make sure RhineLint is installed in the project with command
bun add -D rhine-lint - Run
rl initin the project root directory to initialize and configure your rules (optional)
- Run
rl configto generate config files in cache - Create
prettier.config.jsin project root and write:
export { default } from './node_modules/.cache/rhine-lint/prettier.config.mjs'Since VS Code's Prettier extension cannot directly specify config file path in cache directory yet, we need to manually point to rhine-lint's cache config file.
- Install Prettier extension:
esbenp.prettier-vscode - Add to
.vscode/settings.json:
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}- Install ESLint extension:
dbaeumer.vscode-eslint - Add to
.vscode/settings.json:
{
"eslint.enable": true,
"eslint.options": {
"overrideConfigFile": "./node_modules/.cache/rhine-lint/eslint.config.mjs"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
}
}- Make sure RhineLint is installed in the project with command
bun add -D rhine-lint - Run
rl initin the project root directory to initialize and configure your rules (optional)
- Run
rl configto generate config files in cache - Create
prettier.config.jsin project root and write:
export { default } from './node_modules/.cache/rhine-lint/prettier.config.mjs'Since JetBrains IDE's built-in Prettier save trigger tool cannot specify config file path yet, we need to manually point to rhine-lint's cache config file.
- Open
File→Settings→Languages & Frameworks→JavaScript→Prettier - Select
Manual Prettier configuration - In
Prettier package, select path{project-path}\node_modules\prettier - In
Path to .prettierignore, you can select your.gitignorefile - Check
Run on 'Reformat Code' action - Check
Run on save - Check
Run on paste
- Open
File→Settings→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 save
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.
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| Formatter
- Responsibility: The program's entry point.
- Implementation: Uses the
caclibrary to handle command-line arguments (like--fix,--level).
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")// --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.
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.
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 }>-
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 effect
-
Smart 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 content
-
Ignore 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.
This stores the "source" of Lint rules. It's a Factory Function that exports the createConfig(options) function.
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
}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.
// 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>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.
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,
}
}If you want to add new features to Rhine Lint, follow these paths:
- 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.
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.
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.json
MIT © RhineAI