Skip to content

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.

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.

@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.

Terminal window
yarn add -D @cratis/eslint-plugin-arc @cratis/eslint-config eslint
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.

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:

RuleWhat it does
no-hooks-in-view-modelDisallows 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-importDisallows 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:

'@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.

  • File Index Tracking — the // @generated by Cratis header this processor keys on, and why index.ts deliberately does not carry it.