@trackunit/eslint-plugin-trackunit
v0.6.83
Published
A shared ESLint plugin and configuration preset for Trackunit projects. It bundles Trackunit-specific custom rules alongside curated third-party plugin configurations into ready-to-use flat-config presets for ESLint 9+.
Downloads
5,989
Keywords
Readme
@trackunit/eslint-plugin-trackunit
A shared ESLint plugin and configuration preset for Trackunit projects. It bundles Trackunit-specific custom rules alongside curated third-party plugin configurations into ready-to-use flat-config presets for ESLint 9+.
Quick Start
This plugin ships flat-config presets for common and client-side code. Compose them in your ESLint config:
// eslint.config.cjs
const { configs } = require("@trackunit/eslint-plugin-trackunit");
// Pick the presets that match your project:
module.exports = [...configs.base, ...configs.react];For server, public API, and E2E presets see
@trackunit/eslint-plugin-trackunit-internal(internal, not published to npm).
Presets
| Preset | Purpose | Includes |
| --------------- | ---------------------------- | ---------------------------------------------------------------------- |
| configs.base | Foundation for every project | TypeScript, import, module-boundary, JSDoc, and custom Trackunit rules |
| configs.react | React / browser applications | React, React Hooks, Storybook, Jest + Testing Library overrides |
Combining Presets
Presets are arrays of flat-config objects — spread them in the order you need:
// React application
module.exports = [...configs.base, ...configs.react];configs.base should always come first.
Custom Rules
All custom rules are enabled automatically through the presets under the @trackunit/ prefix. Below is a summary of every rule shipped with the plugin.
Code Quality
| Rule | Severity | Auto-fix | Description |
| ---------------------------------------- | -------- | -------- | ------------------------------------------------------------------------------------------------ |
| @trackunit/no-typescript-assertion | warn | — | Disallows as, angle-bracket, and ! type assertions. as const and as unknown are allowed. |
| @trackunit/no-internal-barrel-files | error | — | Prevents internal index.ts barrel files that are not at the library root. |
| @trackunit/prefer-destructured-imports | — | yes | Converts namespace imports (import * as Foo) to named imports for configured packages. |
React & JSX
| Rule | Severity | Auto-fix | Description |
| ------------------------------------------------------ | -------- | -------- | ------------------------------------------------------------------------------------------ |
| @trackunit/no-template-strings-in-classname-prop | — | — | Disallows template literals in className. Use twMerge() or cvaMerge() instead. |
| @trackunit/require-classname-alternatives | — | yes | Replaces banned class names with approved alternatives. |
| @trackunit/cva-merge-base-classes-as-array | — | yes | Enforces array syntax for cvaMerge base classes when more than one class is used. |
| @trackunit/design-guideline-button-icon-size-match | — | yes | Ensures Icon inside Button uses the correct size prop. |
| @trackunit/prefer-field-components | — | yes | Prefers SelectField/TextField over manually combining Label + base input components. |
| @trackunit/prefer-mouse-event-handler-in-react-props | — | — | Enforces MouseEventHandler<T> typing for onClick* props. |
| @trackunit/prefer-event-specific-callback-naming | — | — | Enforces event-specific naming (e.g. onClickClose over onClose) for click handlers. |
| @trackunit/require-optional-prop-initialization | — | — | Requires optional component props to be initialized inside the component. |
| @trackunit/require-component-prop-contracts | — | — | Requires public component props to satisfy configured prop/interface contracts. |
| @trackunit/require-list-item-virtualization-props | — | — | Requires VirtualizationListItemProps on list items inside <List>. |
| @trackunit/one-component-per-file | error | — | Enforces at most one exported React component per file. exportedOnly: false restricts to one total. |
| @trackunit/component-name-matches-filename | warn | — | Enforces that exported React component names match the filename (e.g. Foo in Foo.tsx). |
Testing
| Rule | Severity | Auto-fix | Description |
| ---------------------------------------------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------- |
| @trackunit/no-jest-mock-trackunit-react-core-hooks | — | — | Disallows jest.mock("@trackunit/react-core-hooks"). Use trackunitProviders() mock builders instead. |
NX / Monorepo
| Rule | Severity | Auto-fix | Description |
| ------------------------------------------------------------ | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| @trackunit/no-internal-graphql-when-tagged-with-gql-public | error | — | Prevents internal GraphQL usage in projects tagged with gql:public. Applied to project.json files. |
| @trackunit/no-deprecated-graphql-fields | error | — | Prevents usage of @deprecated GraphQL fields in projects tagged with dependencies:no-deprecated. Applied to project.json files. |
Storybook
| Rule | Severity | Auto-fix | Description |
| ----------------------------------------------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| @trackunit/require-storybook-folder-landing-page | error | no | Requires a *.docs.mdx landing page (<Meta title>) for every ancestor folder implied by a story's title. Enabled for *.stories.{ts,tsx} files in the react preset. |
Utilities
createSkipWhen
Wraps rules so they are skipped for projects matching NX workspace criteria (e.g. specific tags):
const { createSkipWhen } = require("@trackunit/eslint-plugin-trackunit");
createSkipWhen({
when: { tags: ["scope:tool"] },
plugins: {
"import-x": importXPlugin,
},
rules: {
"import-x/no-extraneous-dependencies": ["error", { /* ... */ }],
},
});findMonorepoRoot
Resolves the NX monorepo root by walking up from the plugin directory until nx.json is found. Useful when rule options need an absolute path to the workspace root.
const { findMonorepoRoot } = require("@trackunit/eslint-plugin-trackunit");
const root = findMonorepoRoot();Requirements
- Node.js >= 24
- ESLint 9+
- TypeScript 5.9+
For more info and a full guide on Iris App SDK Development, please visit our Developer Hub.
Trackunit
This package was developed by Trackunit ApS. Trackunit is the leading SaaS-based IoT solution for the construction industry, offering an ecosystem of hardware, fleet management software & telematics.
