npm package: @next-vibe/checker
Description: Standalone code quality checker (oxlint + eslint + TypeScript) for next-vibe projects
Latest version: 3.0.7

# @next-vibe/checker

Unified code quality for TypeScript projects — oxlint, ESLint, and TypeScript type checking in a single command, running in parallel.

The same checker that powers [unbottled.ai](https://unbottled.ai) and the next-vibe framework, available as a standalone tool for any TypeScript project.

## Why

- **One command instead of three** — `vibe-check` replaces separate `oxlint`, `eslint`, and `tsc` invocations
- **Parallel execution** — all three tools run simultaneously; total time is the slowest, not the sum
- **AI-native** — ships as an MCP server so your AI assistant can run checks directly without shell access

## MCP Setup — AI-First Workflow

Add `vibe-check` as an MCP server and your AI assistant runs checks directly — no copy-pasting terminal output.

**`.mcp.json` in your project root (Claude Code, Cursor, Windsurf):**

```json
{
  "mcpServers": {
    "vibe-check": {
      "command": "bunx",
      "args": ["@next-vibe/checker@latest", "mcp"],
      "env": {
        "PROJECT_ROOT": "/absolute/path/to/your/project"
      }
    }
  }
}
```

The MCP server exposes two tools your AI uses directly:

- **`check`** — run oxlint + ESLint + TypeScript, returns structured results
- **`config`** — create or update `check.config.ts` non-interactively

With `AGENTS.md` in the package, agents know to call `check` instead of running `tsc` or `eslint` in a shell — which means faster feedback, no output truncation, and proper pagination.

## Performance

All three tools run in parallel. TypeScript uses incremental builds (`tsbuildinfo`) for fast repeat runs.

| Project size     | Files | Cold (no cache) | Warm (cached TS) |
|------------------|-------|-----------------|------------------|
| Small            | 13    | ~1.2s           | ~300ms           |
| Medium (Next.js) | 77    | ~4s             | ~440ms           |
| Large (monorepo) | 8k+   | ~25s            | ~3s              |

Cold = first run or after `tsbuildinfo` cleared. Warm = subsequent runs on unchanged files.

## Quick Start — AI-Assisted Setup (Recommended)

Copy this into Claude Code, Cursor, or any agent with tool access:

```
Help me set up @next-vibe/checker for this project.

1. Check my project:
   - Read package.json (package manager? existing lint: biome/eslint/tsc?)
   - Check for existing config files (.eslintrc, biome.json, eslint.config.mjs, check.config.ts)
   - Count .ts/.tsx files in src/

2. Install:
   bun add -D @next-vibe/checker oxlint oxfmt @typescript/native-preview eslint typescript \
     eslint-plugin-react-compiler eslint-plugin-react-hooks \
     eslint-plugin-simple-import-sort typescript-eslint

3. Run the interactive config wizard:
   bunx vibe-check config
   (Answer based on my stack: React? Next.js? i18n? strict types?)

4. Run a full check and show me ALL issues:
   bunx vibe-check src/

5. Ask me:
   - How many issues? Are they real problems or noise?
   - Should we enable --extensive to also check test/generated files?
   - Enable strict mode (no throw, no any, no unknown)?

6. Add MCP server to .mcp.json so you can run checks from this chat:
   {
     "mcpServers": {
       "vibe-check": {
         "command": "bunx",
         "args": ["@next-vibe/checker@latest", "mcp"],
         "env": { "PROJECT_ROOT": "<absolute path to my project>" }
       }
     }
   }

7. If I had biome/standalone eslint configs, remove them.

My project: [INSERT ABSOLUTE PATH]
Package manager: [bun / npm / pnpm]
```

## Quick Start — Manual

```sh
# 1. Install
bun add -D @next-vibe/checker oxlint oxfmt @typescript/native-preview eslint typescript \
  eslint-plugin-react-compiler eslint-plugin-react-hooks \
  eslint-plugin-simple-import-sort typescript-eslint

# 2. Create config (interactive wizard)
bunx vibe-check config

# 3. Run
bunx vibe-check
```

## Installation

```sh
bun add -D @next-vibe/checker
# or
npm install -D @next-vibe/checker
```

### Peer Dependencies

```sh
bun add -D oxlint oxfmt @typescript/native-preview eslint typescript \
  eslint-plugin-react-compiler \
  eslint-plugin-react-hooks \
  eslint-plugin-simple-import-sort \
  typescript-eslint
```

| Package                            | Version    | Purpose                                |
|------------------------------------|------------|----------------------------------------|
| `oxlint`                           | `>=1.0.0`  | Fast Rust-based linter                 |
| `oxfmt`                            | `>=0.40.0` | Formatter (runs automatically on save) |
| `eslint`                           | `>=9.0.0`  | Import sorting, React hooks            |
| `typescript`                       | `>=5.0.0`  | Type checking                          |
| `eslint-plugin-react-compiler`     | `>=19.0.0` | React compiler rules                   |
| `eslint-plugin-react-hooks`        | `>=5.0.0`  | React hooks rules                      |
| `eslint-plugin-simple-import-sort` | `>=12.0.0` | Import sorting                         |
| `typescript-eslint`                | `>=8.0.0`  | TypeScript ESLint parser                              |
| `@typescript/native-preview`       | `>=7.0.0`  | Native TypeScript checker (`tsgo`, 10× faster than tsc) |

## CLI Reference

```sh
vibe-check [paths...]           # Run all checks (oxlint + ESLint + TypeScript)
vibe-check --extensive          # Include test/generated files
vibe-check --timeout=60         # Timeout in seconds (default: 3600)
vibe-check --limit=100          # Max issues to display (default: 20000)
vibe-check config               # Create check.config.ts interactively
vibe-check mcp                  # Start MCP server
vibe-check help                 # List all commands and parameters
```

## Configuration

Run `vibe-check config` to scaffold a `check.config.ts` with an interactive wizard. The wizard asks about your stack (React, Next.js, i18n, strict types) and generates a tailored config.

```ts
import type { CheckConfig } from "@next-vibe/checker/system/check/config/types";

const config = (): CheckConfig => ({
  vibeCheck: {
    timeout: 3600,
    limit: 20000,
    mcpLimit: 20,         // compact output for AI/MCP consumption
    extensive: false,     // true to include test/generated files
    skipEslint: false,    // skip ESLint for maximum speed
    skipOxlint: false,
  },
  oxlint: {
    enabled: true,
    plugins: ["typescript", "oxc", "unicorn", "react", "jsx-a11y", "nextjs"],
    jsPlugins: [
      "@next-vibe/checker/oxlint-plugins/restricted-syntax.js",
    ],
    categories: { correctness: "error", suspicious: "error" },
    rules: { "typescript/no-explicit-any": "error" },
  },
  typecheck: { enabled: true },
  eslint: {
    enabled: true,
    buildFlatConfig(rc, hooks, importSort): EslintFlatConfigItem[] {
      return [{
        plugins: { "simple-import-sort": importSort, "react-hooks": hooks },
        rules: {
          "simple-import-sort/imports": "error",
          "react-hooks/rules-of-hooks": "error",
        },
      }];
    },
  },
  prettier: { enabled: true, singleQuote: false, trailingComma: "all" },
  vscode: { enabled: true, autoGenerateSettings: true },
});

export default config;
```

### Feature Flags

| Flag                | Default | What it enables                             |
|---------------------|---------|---------------------------------------------|
| `react`             | `true`  | React-specific oxlint rules                 |
| `nextjs`            | `true`  | Next.js-specific rules                      |
| `i18n`              | `true`  | i18n string literal checks                  |
| `jsxCapitalization` | `false` | Enforce uppercase JSX component names       |
| `pedantic`          | `false` | Stricter style rules                        |
| `restrictedSyntax`  | `true`  | Ban `throw`, `unknown`, bare `object` types |
| `tsgo`              | `false` | Use `tsgo` native TS checker (10× faster, requires `@typescript/native-preview`) |

### Custom Oxlint Plugins

| Plugin                                                   | What it checks                               |
|----------------------------------------------------------|----------------------------------------------|
| `@next-vibe/checker/oxlint-plugins/restricted-syntax.js` | Bans `throw`, `unknown`, bare `object` types |
| `@next-vibe/checker/oxlint-plugins/jsx-capitalization.js`| Enforces uppercase JSX component names       |
| `@next-vibe/checker/oxlint-plugins/i18n.js`              | Catches untranslated literal strings in JSX  |

You can also write your own oxlint JS plugins and reference them by path in `jsPlugins`.

### VSCode Integration

Set `vscode.enabled: true` and `vscode.autoGenerateSettings: true`. On each run, `vibe-check` writes `.vscode/settings.json` with oxlint, formatter, and TypeScript settings pre-configured.

## Migrating from Biome

```sh
bun remove @biomejs/biome

bun add -D @next-vibe/checker oxlint oxfmt eslint typescript \
  eslint-plugin-react-compiler eslint-plugin-react-hooks \
  eslint-plugin-simple-import-sort typescript-eslint

bunx vibe-check config   # say 'no' to i18n/jsx-cap unless needed
bunx vibe-check src/
```

## Source

Built from the [next-vibe](https://github.com/next-vibe/next-vibe) open-source monorepo.

- [Source code](https://github.com/next-vibe/next-vibe/tree/main/src/app/api/%5Blocale%5D/system/check)
- [Issues](https://github.com/next-vibe/next-vibe/issues)

## License

MIT