---
title: Linting Generated Proxies
---

Generated proxy files live inside your source tree, next to the commands and queries they came from — which means your ESLint config sees them too, unless you tell it not to.

## The Problem

A generated `.ts` file carries a `// @generated by Cratis` header and a `**DO NOT EDIT**` banner, and the proxy generator overwrites it on every Debug build. Any lint finding on that file is unactionable: you cannot fix it by hand without the fix being discarded on the next build, and you cannot fix the generator's output style through your project's lint rules. Left unconfigured, a project either accumulates lint noise it can never resolve, or hand-maintains a path allow-list that has to be kept in sync with every new command and query folder.

## The Fix — `@cratis/eslint-plugin-arc`

[`@cratis/eslint-plugin-arc`](https://www.npmjs.com/package/@cratis/eslint-plugin-arc) ships a `skip-generated-proxies` processor that detects the `// @generated by Cratis` header and skips the file wholesale. Because it keys on the header rather than a path pattern, it works regardless of where a proxy sits — intermixed with hand-written `.ts`/`.tsx` files in the same slice folder, which is the default layout — with no allow-list to maintain.

### Install

```sh
yarn add -D @cratis/eslint-plugin-arc @cratis/eslint-config eslint
```

### Use

```js
// eslint.config.mjs
import cratis from '@cratis/eslint-config';
import arc from '@cratis/eslint-plugin-arc';

export default [
    ...cratis.configs.consumer,
    ...arc.configs.recommended,
    // …your project rules
];
```

With `arc.configs.recommended` composed in, a proxy file is never linted — not even for formatting — so nothing about it shows up as a finding to triage.

## Other Rules in the Plugin

The plugin also ships two rules that are not about generated files, but are worth enabling alongside the processor if you use MVVM view models or MobX:

| Rule | What it does |
| --- | --- |
| `no-hooks-in-view-model` | Disallows React hook calls inside MVVM view models (classes named `*ViewModel`). A view model must be a plain, React-free class — inject a Cratis abstraction instead of calling a hook. |
| `no-direct-mobx-react-import` | Disallows importing directly from `mobx-react`/`mobx-react-lite`. The MobX binding is an internal detail of `@cratis/arc.react.mvvm`, which re-exports `observer` — import it from there so the binding can evolve without breaking consumers. |

`no-hooks-in-view-model` takes options to fit a project's own naming conventions:

```js
'@cratis/arc/no-hooks-in-view-model': ['error', {
    classSuffix: 'ViewModel',          // class-name suffix that marks a view model
    hookPattern: '^use[A-Z]',          // bare-identifier calls treated as hooks
    additionalHooks: ['injectQuery'],  // extra call names to forbid
}]
```

Only bare-identifier calls (`useState(...)`) are flagged — a member call like `this.useDefaults()` is not, so a view-model method that merely starts with `use` is safe.

## See Also

- [File Index Tracking](/arc/backend/proxy-generation/file-index-tracking/) — the `// @generated by Cratis` header this processor keys on, and why `index.ts` deliberately does not carry it.
