{"id":25891,"library":"lintcn","title":"lintcn","description":"A CLI tool for browsing, installing, and managing custom TypeScript lint rules as local Go source files, inspired by shadcn for UI components. Current version 0.9.0; releases appear every 2–3 weeks. Unlike ESLint plugins or convention-based linters, lintcn copies rule source into your project so you fully own and can customize each rule. Powered by tsgolint (Go-based TypeScript linter with type-aware analysis). Minimizes false positives by running only explicitly added rules. Supports automatic fixes, warning severity, and snapshot testing.","status":"active","version":"0.9.0","language":"javascript","source_language":"en","source_url":"https://github.com/remorses/lintcn","tags":["javascript","lint","linter","typescript","tsgolint","oxlint","type-aware","shadcn","rules"],"install":[{"cmd":"npm install lintcn","lang":"bash","label":"npm"},{"cmd":"yarn add lintcn","lang":"bash","label":"yarn"},{"cmd":"pnpm add lintcn","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Executes Go binary for linting; requires Go (or cached binary) at runtime","package":"node","optional":true}],"imports":[{"note":"ESM-only since v0.1.0. TypeScript types are shipped. Do not use require().","wrong":"const lintcn = require('lintcn'); // CJS require fails: package is ESM-only","symbol":"default","correct":"import lintcn from 'lintcn'"},{"note":"The package is primarily a CLI tool. Subcommands: add, remove, lint, list, clean.","wrong":"npx lintcn install <url>  // 'install' is not a valid subcommand; use 'add'","symbol":"CLI binary","correct":"npx lintcn add <url>"},{"note":"The package exports a single default object for programmatic use. The CLI is invoked via npx or the bin script.","wrong":"import { lintcn } from 'lintcn' // Named export 'lintcn' does not exist; use default import","symbol":"lintcn","correct":"import lintcn from 'lintcn'"}],"quickstart":{"code":"const { execSync } = require('child_process');\n// Install lintcn as devDependency\nexecSync('npm install -D lintcn', { stdio: 'inherit' });\n\n// Add a rule from tsgolint repository\nexecSync('npx lintcn add https://github.com/oxc-project/tsgolint/blob/main/internal/rules/no_floating_promises/no_floating_promises.go', { stdio: 'inherit' });\n\n// Lint the TypeScript project\nexecSync('npx lintcn lint --tsconfig tsconfig.json', { stdio: 'inherit' });\n\n// List installed rules\nexecSync('npx lintcn list', { stdio: 'inherit' });","lang":"javascript","description":"Install lintcn, add a type-aware lint rule file from the tsgolint repository, run lint, and list installed rules."},"warnings":[{"fix":"Check for .lintcn/ directory explicitly in CI scripts if you require rules to be installed.","message":"lintcn lint exits with 0 when no .lintcn/ directory exists; prints a helpful message instead of failing. Do not rely on exit code for presence of rules.","severity":"gotcha","affected_versions":">=0.7.1"},{"fix":"For each rule file in .lintcn/, move it into a new subfolder named after the rule (snake_case). The Go package declaration inside the file should match the folder name.","message":"Rule folder structure changed from flat .lintcn/*.go to subfolders .lintcn/{rule_name}/*.go in v0.6.0. Existing rules must be moved to subfolders.","severity":"breaking","affected_versions":">=0.6.0 <0.7.0"},{"fix":"Use --all-warnings to see all warnings, and configure rule severity via // lintcn:severity warn in rule source.","message":"By default only warning rules with severity 'warn' do not fail CI; error severity rules exit with code 1 even if only one error is found.","severity":"gotcha","affected_versions":">=0.7.0"},{"fix":"Update to v0.5.0 or later. If using older version, avoid using --tsgolint-version with untrusted input.","message":"Path traversal vulnerability in --tsgolint-version flag allowed arbitrary file read via version string like '../../etc'. Fixed in v0.5.0 by validating version pattern.","severity":"security","affected_versions":">=0.2.0 <0.5.0"},{"fix":"Update rule Go files: replace 'github.com/typescript-eslint/tsgolint/internal/rule' with 'github.com/typescript-eslint/tsgolint/pkg/rule' (and similarly for internal/utils to pkg/utils).","message":"Rule import paths changed from 'internal/rule' to 'pkg/rule' in v0.4.0. Old rule files using internal/rule will fail to compile.","severity":"deprecated","affected_versions":">=0.4.0"},{"fix":"Use npx lintcn add to add each desired rule from the tsgolint repository. Alternatively, configure a separate tsgolint run for built-in rules.","message":"In v0.3.0, lintcn changed from running all 44 built-in tsgolint rules to running only custom rules in .lintcn/. Projects relying on built-in rules must explicitly add each rule needed.","severity":"breaking","affected_versions":">=0.3.0"},{"fix":"Upgrade to v0.5.0 or later to avoid intermittent failures when running multiple lintcn processes simultaneously.","message":"Concurrent lintcn lint runs can corrupt each other's Go build workspace if not using unique content-hash workspaces. Fixed in v0.5.0 via per-content-hash workspaces.","severity":"gotcha","affected_versions":"<0.5.0"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Run 'npm install -D lintcn' to add it as a devDependency.","cause":"Attempting to import or require lintcn as a library without installing it.","error":"Error: Cannot find module 'lintcn'"},{"fix":"Use 'npx lintcn add <url>' to install a rule.","cause":"Using non-existent subcommand 'install' instead of 'add'.","error":"Error: Unknown command: install"},{"fix":"Rename the folder to match the package declaration, or edit the package declaration to match the folder name (e.g., package no_unhandled_error in folder .lintcn/no_unhandled_error/).","cause":"When writing a custom rule, the Go package name in the .go file must equal the folder name under .lintcn/.","error":"package declaration must match folder name"},{"fix":"Replace 'github.com/typescript-eslint/tsgolint/internal/rule' with 'github.com/typescript-eslint/tsgolint/pkg/rule'.","cause":"Using outdated import path for the tsgolint rule API (changed in v0.4.0).","error":"Rule import path 'internal/rule' not found"},{"fix":"Use a valid version like 'v0.9.2' for --tsgolint-version.","cause":"Providing an invalid --tsgolint-version value that doesn't match the expected pattern (e.g., starting with 'v' followed by digits and dots).","error":"lintcn lint: tsgolint version flag traversal detected"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}