> For AI agents: the complete documentation index is available at /byethrow/llms.txt, the full documentation bundle is available at /byethrow/llms-full.txt.

# Linter Plugin

`@praha/byethrow-oxlint` is an [Oxlint](https://oxc.rs/docs/guide/usage/linter) plugin that enforces best practices when using `@praha/byethrow`.

## Installation

```bash
npm install -D @praha/byethrow-oxlint
```

## Setup

### Using the recommended preset

The easiest way to get started is to extend the recommended preset. It enables all rules with their default settings.

```ts title="oxlint.config.ts"
import oxlintByethrowPlugin from '@praha/byethrow-oxlint';
import { defineConfig } from 'oxlint';

export default defineConfig({
  extends: [
    oxlintByethrowPlugin.recommended,
  ],
});
```

### Configuring rules manually

If you need fine-grained control, you can load the plugin and enable individual rules:

```ts title="oxlint.config.ts"
import { defineConfig } from 'oxlint';

export default defineConfig({
  jsPlugins: [
    {
      name: 'byethrow',
      specifier: '@praha/byethrow-oxlint',
    },
  ],
  rules: {
    'byethrow/consistent-namespace': 'error',
    'byethrow/no-ambiguous-error-type': 'error',
    // ...
  },
});
```

## Settings

You can customize how the plugin detects byethrow imports by adding a `byethrow` key under `settings`. This is useful when you re-export `@praha/byethrow` from your own package.

| Option      | Type                 | Default             | Description                                     |
| ----------- | -------------------- | ------------------- | ----------------------------------------------- |
| `module`    | `string \| string[]` | `"@praha/byethrow"` | Module specifiers to treat as byethrow          |
| `namespace` | `string \| string[]` | `["Result", "R"]`   | Import names to treat as the byethrow namespace |

```ts title="oxlint.config.ts"
import { defineConfig } from 'oxlint';

export default defineConfig({
  settings: {
    byethrow: {
      module: ['@praha/byethrow', '@my-org/result'],
      namespace: ['Result', 'R'],
    },
  },
});
```

## Rules

| Rule                                                                                       | Description                                            | Fixable |
| ------------------------------------------------------------------------------------------ | ------------------------------------------------------ | ------- |
| [consistent-namespace](/byethrow/guide/ecosystem/linter/consistent-namespace.md)           | Enforce consistent namespace alias                     | ✅       |
| [no-ambiguous-error-type](/byethrow/guide/ecosystem/linter/no-ambiguous-error-type.md)     | Disallow non-specific error types                      |         |
| [no-ambiguous-success-type](/byethrow/guide/ecosystem/linter/no-ambiguous-success-type.md) | Disallow non-specific success types                    |         |
| [no-negated-type-guards](/byethrow/guide/ecosystem/linter/no-negated-type-guards.md)       | Disallow negated `isSuccess`/`isFailure`               | ✅       |
| [no-throw-in-callback](/byethrow/guide/ecosystem/linter/no-throw-in-callback.md)           | Disallow `throw` in byethrow callbacks                 |         |
| [no-try-catch-in-callback](/byethrow/guide/ecosystem/linter/no-try-catch-in-callback.md)   | Disallow `try-catch` in byethrow callbacks             |         |
| [prefer-result-async](/byethrow/guide/ecosystem/linter/prefer-result-async.md)             | Prefer `ResultAsync` over `Promise<Result>`            | ✅       |
| [prefer-result-matchers](/byethrow/guide/ecosystem/linter/prefer-result-matchers.md)       | Prefer `toBeSuccess`/`toBeFailure` matchers            | ✅       |
| [prefer-result-maybe-async](/byethrow/guide/ecosystem/linter/prefer-result-maybe-async.md) | Prefer `ResultMaybeAsync` over `Result \| ResultAsync` | ✅       |
