Skip to content

feat: support localisation of rule messages#141

Open
k-yle wants to merge 2 commits intoeslint:mainfrom
k-yle:rfc-141
Open

feat: support localisation of rule messages#141
k-yle wants to merge 2 commits intoeslint:mainfrom
k-yle:rfc-141

Conversation

@k-yle
Copy link

@k-yle k-yle commented Jan 14, 2026

This is an RFC for eslint/eslint#19210, which superseeds #128. Copying the document's first section:

Summary

This RFC proposes adding localisation support for rule messages. This allows rules to define messages in multiple langauges, not just English.
Translations could be defined by plugin authors, or in a third-party package, similar to the @types/* ecosystem.

For example, instead of:

{{left}} can be removed because it is already included by {{right}}

Someone who prefers Japanese would see:

{{left}}は既に{{right}}に含まれているため、不要です。

(example from eslint-plugin-regexp)

This is a similar situation to JavaScript libraries which don't want to maintain TypeScript definitions.
In this case, contributors can maintain the types in [DefinitelyTyped](http://github.com/DefinitelyTyped/DefinitelyTyped).

This RFC proposes an equivalent monorepo, tentatively called "_eslint-translations_".

Choose a reason for hiding this comment

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

Really interesting idea, and not only addresses the problem of plugin authors "not wanting to maintain" their own translations, but also plugin authors that just haven't had the chance to add them yet (also a similar use case for Definitely Type).
One question I'd have is, who are you proposing is responsible for maintaining this new monorepo, and who would own the npm scope? While the DT repo is intentionally self serve, I'm sure it took a lot of engineering effort to build out the tooling to make it that way. Who would be doing that initial build-out? You have the governance listed in open questions, but I think there's more than ongoing maintenance / governance that would need to be figured out.

Copy link
Author

Choose a reason for hiding this comment

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

At the very least, I hope this could be an eslint-community project, for the same reasons mentioned in RFC #91. That means the npm scope @eslint-translations/* could be owned and managed in the way as @eslint-community/*.

In terms of maintenance: I'm happy to assist myself, but I don't have any 'reputation' amongst the eslint community: the open-source projects I maintain are all unrelated to eslint, I only contribute occasional PRs to eslint plugins. With that said, I would certainly volunteer to do the initial build-out and ongoing maintenance, if everyone is happy with this.

**Case 2:** If translations cannot be found in the rule itself, we need to:

- check if `@eslint-translations/{packageName}` exists with `require.resolve`
- if yes, read that package and check if it contains a matching language

Choose a reason for hiding this comment

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

What would the structure of these language packages look like? Is it a single default export with similar shape as the message_translations prop under meta?

Copy link
Author

Choose a reason for hiding this comment

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

yes, I think that's the only thing that needs to be exported. Either:

export default {
  'es': { avoidName: 'Evite utilizar variables llamadas {{name}}' },
  'zh-Hans': { avoidName: '避免使用名为{{name}}的变量' },
}

or perhaps a seperate file for each language. For example es.js[on]:

export default {
  avoidName: 'Evite utilizar variables llamadas {{name}}'
}

Copy link
Author

Choose a reason for hiding this comment

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

My comment above was incorrect. A third-party translation package also needs to define the rule name, since messageIds are not globally-unique.

So the structure would be more like:

// es-ES.js
export default {
  'optimal-quantifier-concatenation': {
    avoidName: 'Evite utilizar variables llamadas {{name}}'
  },
  'no-constant-condition': {
    error: 'condición constante inesperada'
  }
}

Choose a reason for hiding this comment

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

Would it make sense to include some mention of that (and maybe this example) in the RFC text?

Copy link
Author

Choose a reason for hiding this comment

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

agreed, done

@fasttime
Copy link
Member

Thanks for the RFC @k-yle! I'm not sure I see a strong benefit in introducing a framework for translating rule messages while the rest of ESLint, including core, CLI, built-in formatters, etc., would remain untranslated. ESLint contains a wide range of messages, many of which aren't even grouped in conceptual units, and just appear as standalone strings in the codebase ("Oops! Something went wrong! :("). From what I've seen, this pattern is fairly common across many software projects.

If internationalization is a goal, I think it would make more sense to start from the core outward: establish a machanism for translating ESLint's own messages first, and then consider rules and plugins. Even then, I'm unsure whether the added maintenance cost would be justified. For example, our non-English sites like https://zh-hans.eslint.org/ receive very little traffic despite the enthusiasm some contributors have for providing translations.

Anyway, this is just my opinion, and I'd be interested to hear how others feel about this proposal.

@k-yle
Copy link
Author

k-yle commented Jan 29, 2026

From my experience, users very rarely encounter eslint's core messages, except when updating the configuration file, which they might do once every few months. On the other hand, rule-messages are seen hundreds of times per day.

So rule-messages are significantly more important than core-messages, and arguably even more important than docs.


Another key point: eslint rules are effectively a teaching resource for junior engineers. If you don't speak English well, it's time-consuming to understand a complex error, and it's very tempting just to click Fix with AI in your IDE, instead of reading the message and learning.
image
There's academic research which confirms this effect, and real examples of eslint plugins that use non-English langauges.


Regarding your maintenance cost concerns @fasttime: could you please clarify whether you're refering to the (very minimal) changes required in eslint-core, or the complexity of the seperate translations repository?

@nzakas
Copy link
Member

nzakas commented Feb 3, 2026

Thanks for looking into this. While I understand the idea behind this, I just don't think it's practical given the nature of the ESLint ecosystem. Creating a DefinitelyTyped-style solution is just maintenance overhead with very little overall benefit. Whenever rule messages change, there would be a lag between that and when the separately-managed packages were updated.

Plus, I think it's much easier for someone who doesn't know english to paste the error message into Google, find the documentation, and then have the browser translate the documentation into their preferred language. That will actually give the useful context they are looking for.

So overall, I'm 👎 to this proposal.

@k-yle
Copy link
Author

k-yle commented Feb 16, 2026

okay, would a much simpler proposal have any chance of proceeding? For example, if we completely remove the third-party translation idea, any only allow plugins to define messageTranslations themselves?

That part of the proposal is quite trivial to implement in eslint-core, and gives plugins authors full control over whether they want to allow translations.

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.

5 participants

Comments