Skip to content

Conversation

@timsmallwood
Copy link

@timsmallwood timsmallwood commented Sep 17, 2025

Add comprehensive ESLint integration for JavaScript/TypeScript linting and formatting

Why

ESLint is the de facto standard linting tool for JavaScript and TypeScript projects. This PR adds complete ESLint
integration to Pants, filling a significant gap in the JavaScript/TypeScript toolchain support and enabling
consistent code quality enforcement across monorepo projects.

What

  • New experimental backend: pants.backend.experimental.javascript.lint.eslint
  • Dual functionality: Supports both pants lint and pants fmt goals
  • Comprehensive config discovery: Supports all ESLint config file types (flat configs, legacy configs,
    package.json)
  • TypeScript support: Via configurable extra dev dependencies
  • JSON output mode: With parsed error/warning summaries
  • Skip field support: skip_eslint=True on individual targets
  • Extensive test coverage: Integration tests, edge cases, and comprehensive documentation

Usage

# pants.toml
[GLOBAL]
backend_packages.add = [
  "pants.backend.javascript",
  "pants.backend.experimental.javascript.lint.eslint",
]

pants lint src/js/::
pants fmt src/js/::

This implementation provides a solid foundation for JavaScript/TypeScript code quality in Pants-managed projects.

@cburroughs
Copy link
Contributor

Thanks for the contribution! Could you flesh out the "why" and "what" of the PR description?

@sureshjoshi sureshjoshi self-requested a review October 17, 2025 00:29
@sureshjoshi sureshjoshi self-assigned this Oct 20, 2025
Copy link
Contributor

@riisi riisi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timsmallwood Thanks for submitting this - it would definitely be good to have support for eslint.

I've reviewed it briefly - looking at the implementation mostly and not the tests at all yet. Not a maintainer, but I think I have an idea of what would be expected.

I have further questions about the architecture which I've not had time to look into.

  • Caching: It looks like this is not implemented. Is it absolutely needed or can it be dropped for now to reduce scope?
  • Multi-project/resolve handling: How would it work across independent projects with different eslint versions? Does eslint need to operate in a package/project context, or does it just run per-file? In terms of existing goals - is it more like Prettier, or more like Typescript?

)
```

## Configuration Files
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better here to link to the eslint docs on config file formats and just state that Pants supports them (to avoid re-documenting here, plus this doc is already quite long).


## Supported File Types

ESLint in Pants supports:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there other types that are currently unsupported? Or is this a generic statement implying that Pants supports all the types one would want to use?

Are .jsx and .tsx files supported?


### Prettier Integration

ESLint and Prettier can work together. If you're using both tools, consider:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The numbering implies to me that all of these things should be done in order - I'm not sure that's the case?

Does Pants support running prettier first, then eslint by default, or we need to consider the order of pants fmt lint ... ?

I do think covering this usage is important FWIW - it's been a bit of a minefield in personal past experience to get these working together. I think if we can offer some opinionated guidance, that would be helpful.

};
```

**Note**: ESLint can lint TypeScript but has limited formatting capabilities for TypeScript-specific syntax. For comprehensive TypeScript formatting, consider using Prettier alongside ESLint.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it might make sense to have one docs section on linting and formatting, like with Python - https://www.pantsbuild.org/2.27/docs/python/overview/linters-and-formatters - but we can leave it for now.

```

:::tip Cache Location
ESLint will create a `.eslintcache` file to store cache data. Consider adding this to your `.gitignore`:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering how this works - wouldn't this be in sandbox and not need to be ignored?


wants_json = False
if getattr(eslint, "json_output", False):
# Only add json format if user did not already specify a formatter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can json just be a default option instead?

if wants_json:
try:
parsed = json.loads(stdout or "[]")
if isinstance(parsed, list):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No else?

summary = f"ESLint summary: {errors} errors, {warnings} warnings\n\n"
stdout = summary + stdout
except Exception:
pass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to swallow the exception?

@@ -0,0 +1,25 @@
# Copyright 2025 Pants project contributors (see CONTRIBUTORS.md).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, following the pattern from the other javascript/typescript plugins, that the most of the eslint code should not be located under backend/experimental - only register.py -- see e.g. prettier.

),
)

extra_dev_dependencies = StrListOption(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can see, this isn't used in the current implementation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants