Skip to content

feat: link rule IDs to docs URLs in stylish formatter - #151

Open
Norbiros wants to merge 1 commit into
eslint:mainfrom
Norbiros:hyperlink-rule-docs-in-stylish-formatter
Open

Norbiros wants to merge 1 commit into
eslint:mainfrom
Norbiros:hyperlink-rule-docs-in-stylish-formatter

Conversation

@Norbiros

Copy link
Copy Markdown

Summary

This RFC proposes adding clickable rule documentation links to ESLint’s stylish formatter using OSC 8 terminal hyperlinks. Links are opt-in via FORCE_HYPERLINK in ESLint v10 and enabled by default for terminal output in v11, with an option to disable them. The visible output remains unchanged.

Related Issues

eslint/eslint#21073

@fasttime fasttime added the Initial Commenting This RFC is in the initial feedback stage label Aug 3, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the RFC @Norbiros. Can you clarify what happens when FORCE_HYPERLINK=1 is set and stdout is not a TTY terminal?

- `json` and `json-with-metadata` are machine-readable; `json-with-metadata` already exposes rule metadata.
- `html` already links rule IDs using anchors.

Nothing in this design prevents a follow-up from applying the same helper to another formatter, and the support-detection helper should be written so it can be reused.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The helper is internal. That means only other built-in formatters will be able to reuse it?

The formatter wraps rule IDs that have a `docs.url` using a small internal helper for support detection, escaping, and sequence construction. In v11, the CLI passes whether its actual output destination is a terminal through the formatter context.


Hyperlink support is decided once per formatter invocation. `FORCE_HYPERLINK` takes precedence: `0` and `false` disable links, while any other value enables them, including for piped or redirected output. The name and semantics follow `supports-hyperlinks`, `terminal-link`, and the established `FORCE_COLOR` convention.

Without the environment variable, hyperlinks are disabled in v10. In v11, the CLI enables them only when stdout is a TTY and `--output-file` is not set. It passes this decision to the formatter through an internal context field so the formatter does not mistake a file for terminal output. Programmatic formatter use remains default-off because ESLint cannot know where the returned string will be written; consumers can opt in with `FORCE_HYPERLINK`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the discussion would be easier if you could clearly separate the v10 changes from the changes planned for v11, and use a separate section to note the similarities and differences.

@nzakas nzakas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This RFC reads like it was written by AI. Can you clarify if it was?

Comment on lines +14 to +15
- In ESLint v10, hyperlinks are opt-in and are emitted only when the `FORCE_HYPERLINK` env variable is set.
- In ESLint v11, hyperlinks are emitted by default when ESLint is writing to a terminal, and users can opt out with `FORCE_HYPERLINK=0`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It seems like we should use a feature flag for this?
https://eslint.org/docs/latest/flags/

@mdjermanovic mdjermanovic Sep 23, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe the idea is to keep a way to force/disable hyperlinks in ESLint v11 and above for use cases where the desired outcome is the opposite of what ESLint would automatically determine, so feature flags might not be appropriate for this purpose as they are intended for experimental or future breaking changes only.

@mdjermanovic

Copy link
Copy Markdown
Member

@Norbiros are you still working on this? There are several review suggestions, could you take a look?

@Norbiros

Copy link
Copy Markdown
Author

Sorry for all the delays. I've been really busy over the past few weeks. Also, just to be transparent, this PR was partially written with the help of AI, as I didn't have enough time while writing it and I apologize for that.

As soon as I have some time, I'll revisit the PR, address all the concerns that were raised, and work on improving its overall quality.


Hyperlink support is decided once per formatter invocation. `FORCE_HYPERLINK` takes precedence: `0` and `false` disable links, while any other value enables them, including for piped or redirected output. The name and semantics follow `supports-hyperlinks`, `terminal-link`, and the established `FORCE_COLOR` convention.

Without the environment variable, hyperlinks are disabled in v10. In v11, the CLI enables them only when stdout is a TTY and `--output-file` is not set. It passes this decision to the formatter through an internal context field so the formatter does not mistake a file for terminal output. Programmatic formatter use remains default-off because ESLint cannot know where the returned string will be written; consumers can opt in with `FORCE_HYPERLINK`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In this RFC, we should specify how CLI passes the decision to the formatter. Is it a new field of ResultsMeta (https://eslint.org/docs/latest/integrate/nodejs-api#-loadedformatter-type), what would be its name, and how exactly CLI calculates the value.

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

Labels

feature Initial Commenting This RFC is in the initial feedback stage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants