Issues
This document serves as a guide for how you might manage our GitHub Issues, also known as issue triaging.
Use your best judgement when triaging issues, and most of all remember to be encouraging, friendly, and kind when responding to users. Many users are new to open source and/or typed linting. It's imperative we give them a positive, uplifting experience.
If you're ever unsure on any part of issue management, don't hesitate to loop in a maintainer that has more context to help!
Governance
Per the scales from Contribution Tiers > Pointing:
- Straightforward: at reviewer discretion, may be marked as approved by any committer or maintainer. This includes docs enhancements, bug fixes, and feature additions.
- Non-straightforward: may be marked as approved with either two committer approvals or one maintainer approval. These include significant internal refactors and non-breaking public API changes.
- "Unusual"-categorized: require a public discussion followed by two maintainer approvals. These include significant refactors with cross-project and public API ramifications.
Issue Flow
We include a set of common responses to issues in .github/replies.yml
, intended to be used with the Refined Saved Replies extension.
Don't treat these as exact responses you must use: they're just a starting copy+paste helper.
Please do adopt your specific responses to your personal tone and to match the thread for non-straightforward issues.
Issues pending triage are searchable with the triage
label.
That label is added automatically when a new issue is created.
Most issues go through the following review flow when created or updated:
- A maintainer ensures the issue is valid:
- If the poster didn't fill out an appropriate template with enough information:
- Add the
please fill out the template
andawaiting response
labels, and remove thetriage
label - Ask the poster for more information using a Needs More Info response
- Add the
- If it's a duplicate of an issue that already exists:
- Add the
duplicate
label and remove thetriage
label - If it's an obvious duplicate, post a Clearly Duplicate Issue response linking to the existing issue
- If it's not an obvious duplicate, link to the existing issue and explain why
- Close the issue as not planned
- Add the
- If the code is working as intended:
- Add the
working as intended
label and remove thebug
andtriage
labels - If the behavior is due to the user doing something wrong, such as an incorrect config:
- Add the
fix: user error
label - This issue search has some examples of closing comments
- Add the
- If the behavior is otherwise expected, this issue search has some examples of closing comments
- You needn't go into too much detail in your comment - just enough to explain it
- Close the issue as not planned
- Add the
- If issue contains an enhancement-like request that is unlikely to be implemented on the typescript-eslint side:
- Add the
wontfix
label and removetriage
label - Issue search with some examples of closing comments
- If there're any alternatives or approaches to meet the request, it would be nice to suggest them
- Close the issue as not planned
- Add the
- If the issue requires further discussion or community engagement evaluation:
- Add the
evaluating community engagement
label and remove thetriage
label
- Add the
- If the poster didn't fill out an appropriate template with enough information:
- If the report is valid, add the
accepting prs
label and remove thetriage
label - If you know the rough steps for a fix, consider writing a comment with links to codebase to help someone put together a fix
- If you think that the fix is relatively straightforward, consider also adding the
good first issue
label
Whenever an issue is waiting for the reporter to provide more information, it should be given the awaiting response
label.
When more information is provided:
- If you have time to go through the triage flow again, do so
- If you don't have time, add the
triage
label and remove theawaiting response
label
If your link is both a "permalink" (includes a commit hash instead of a branch name) and has a line number/line range then GitHub will embed the code in your comment.
When viewing a file in GitHub pressing y
will update the URL to a "permalink" with the current commit hash, then you can select the relevant lines and paste that URL into the comment.
Looking for Duplicates
It's worth noting that, occasionally, a user will intentionally raise a duplicate issue because they feel the original issue was closed when it shouldn't have been. If this is the case, you should read the original issue to gather context, understand the reason for it being closed, and determine if the new issue raises any new or relevant point that requires addressing.
Determining Whether Code is Working As Intended
As you become more familiar with the codebase and how everything works, this will be easier to do intuitively, but to begin with, this will likely involve investigating the documentation, code, and tests to determine if it's a bug or working as intended. In general, if there is a passing test or documented example that is the same as or similar to the repro code — that indicates it's working as intended. If you can't find anything that matches, use your best judgement based on the spirit of the code.
Community Engagement Evaluation
In most cases, maintainers have a pretty good idea of how people write code and what most users of the typescript-eslint tooling want. However, there are cases when maintainers can't confidently choose the most reasonable approach to solving a particular problem:
- The issue subject relates to a library/framework that the maintainers are not familiar with. Therefore, they don't know the idiomatic patterns associated with it.
- There is a new syntax or a new feature - sometimes it's hard to guess how people might use that feature.
- The issue was about to be closed, but someone made a compelling argument. This requires further discussion to find a viewpoint that most people agree on.
3-6 months after the issue is labeled evaluating community engagement
, the engagement of community is evaluated:
- If the community was active and common ground was found, the issue is labeled as
accepting prs
- Otherwise, the issue is closed as not planned with the
wontfix
label
For requests that can be implemented outside of typescript-eslint, be sure to mention any relevant APIs such as Custom Rules that can be used.
Skipping Steps
As you become more familiar with the codebase and how it's supposed to behave you'll be able to skip steps or do things out of order as you see fit. For example, you may be able to identify if a bug report is "working as intended", or you might recognize an issue as a duplicate without having a completely filled-out issue. In such cases you can forgo the back-and-forth and just skip to the closing steps.
Specific Issue Types
🐛 Bug Reports
🐞 "Simple" Bugs
A simple bug is a bug that can be reproduced in a single TS file plus an ESLint config (and possibly a TSConfig) - i.e. an issue reproducible on our playground. The vast majority of bug reports fall into this category.
If you cannot reproduce the issue as described using the issue's provided playground reproduction, it has not provided enough information. Consider using a specific response like the Needs Playground Reproduction response.
🦟 "Complex" Bugs
A complex bug is a bug that requires multiple files to reproduce. This is the rarer case, but does happen when people are using library types or if there are issues when types are imported.
These bugs should be reported with a link to a GitHub repository that can be checked out to reproduce the issue. If you cannot reproduce the issue as described using repository's README.md and issue description, it has not provided enough information. Consider using a specific response like the Needs Full Reproduction response.
🏗 Feature Requests
For any feature request, make sure the requested support is either:
- Very useful for at least one commonly used way to run TypeScript (e.g. tsc-built CLI package; bundler-managed web app)
- Relevant for most projects that would be using typescript-eslint
We avoid features that:
- Are only relevant for a minority of users, as they aren't likely worth the maintenance burden
- Aren't TypeScript-specific (e.g. should be in ESLint core instead)
- Are only relevant with specific userland frameworks or libraries, such as Jest or React
- Are for "formatting" functionality (we strongly recommend users use a separate dedicated formatter)
✨ Rule Enhancements
We're generally accepting of rule enhancements that meet the above feature request criteria. If a rule enhancement would substantially change the target area of the rule, consider whether it should instead be a new rule. Common signs of this are the rule's original name now being inaccurate, or some options being relevant just for the old functionality.
Enhancements that can cause new reports to be reported are considered breaking changes. We have two common strategies for them:
- Treat the enhancement as a breaking change, and block merging it until the next major version
- Add an option to disable the new logic: which is a breaking change if opt-in, and a non-breaking change if opt-out
- Add an option to enable the new logic: which is a breaking change if opt-out, and a non-breaking change if opt-in
See Can we standardize logical direction of rule options? for context on naming options.
For enhancements meant to limit which kinds of nodes the rule targets, mark the issue as blocked on RFC: Common format to specify a type or value as a rule option.
🚀 New Rules
We're generally accepting of new rules that meet the above feature request criteria.
The biggest exception is rules that can roughly be implemented with @typescript-eslint/no-restricted-types
and/or no-restricted-syntax
.
Pruning Old Issues
Every so often, we like to search for open issues awaiting response
to find ones that might have been forgotten.
Our flow for issues that have been waiting for >=1 month is:
- Ping the author with a message like the Checking In template
- Add the
stale
label to the issue - Wait 2 weeks
- If they still haven't responded, close the issue with a message like the Pruning Stale Issue template