Skip to content

Add basic ESLint config, lint script and lint CI job#1640

Merged
delucis merged 34 commits intowithastro:mainfrom
hippotastic:add-eslint
Aug 19, 2025
Merged

Add basic ESLint config, lint script and lint CI job#1640
delucis merged 34 commits intowithastro:mainfrom
hippotastic:add-eslint

Conversation

@hippotastic
Copy link
Copy Markdown
Contributor

Description

  • Adds ESLint to the Starlight repo to help catch non-recommended code patterns and bugs. It can be run locally using pnpm lint from the repo root.
  • Adds a lint job to the CI workflow that should generate annotations on PRs to make it easier to see any found issues in context.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 20, 2024

🦋 Changeset detected

Latest commit: bec083a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@astrojs/starlight Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 20, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
starlight ✅ Ready (Inspect) Visit Preview Mar 22, 2024 1:49pm

@liruifengv
Copy link
Copy Markdown
Member

How about biome?

@hippotastic
Copy link
Copy Markdown
Contributor Author

How about biome?

Good question! To be honest, I didn't try Biome yet, but I've heard good things about it. I was simply sticking with ESLint as it's part of my default setup I use for all projects and as it's also used in other Astro repos. Personally, I'm open for adopting Biome if it provides an experience for contributors that is on par with ESLint and finds at least the same issues.

Copy link
Copy Markdown
Member

@HiDeoo HiDeoo left a comment

Choose a reason for hiding this comment

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

Did not have time yet to deep dive in the reported errors individually so it's mostly a general review of the approach and the config but I thought I would still share it to get the discussion started.

One last question, I see the "Unchanged files with check annotations" in GitHub:

  • How does it work?
  • Why is it only reporting so few errors?

@hippotastic
Copy link
Copy Markdown
Contributor Author

Thank you for the great suggestions! I commented on all of them and applied most of them.

One last question, I see the "Unchanged files with check annotations" in GitHub:

  • How does it work?
  • Why is it only reporting so few errors?

To my knowledge, this is a beta GitHub feature that's using an error matcher to automatically create annotations from the errors contained in the ESLint CLI output. I don't know why it's only reporting a subset of errors. Maybe the output is limited by default, or the error matcher doesn't recognize some of the ESLint output yet. I wanted to use a different approach with a JSON output file and a separate annotation step at first, but this doesn't work on PRs coming in from forks due to security reasons, so I had to remove this again and not GitHub only applies its default matching logic.

@hippotastic hippotastic changed the title Add basic ESLint config, lint and lint:ci scripts, and lint CI job Add basic ESLint config, lint script and lint CI job Mar 20, 2024
@HiDeoo
Copy link
Copy Markdown
Member

HiDeoo commented Mar 20, 2024

To my knowledge, this is a beta GitHub feature that's using an error matcher to automatically create annotations from the errors contained in the ESLint CLI output. I don't know why it's only reporting a subset of errors. Maybe the output is limited by default, or the error matcher doesn't recognize some of the ESLint output yet. I wanted to use a different approach with a JSON output file and a separate annotation step at first, but this doesn't work on PRs coming in from forks due to security reasons, so I had to remove this again and not GitHub only applies its default matching logic.

I see, thanks for the explanation. I was wondering if you had something special in place for this or not.

How about biome?

I actually just did a test right now, I'm still amazed how crazy fast it is and how much easier the configuration is. By turning off only style rules, we get pretty much to the same number of errors as ESLint, altho unfortunately, the errors that started the idea of this PR are not reported yet. Maybe in the future 🤞


I think configuration and setup wise, we are pretty much close to the minimum of what we would need. What do you think could be a good next step Hippo? Maybe making a list of all errors reported and figuring out a smaller list of obvious rules we want enabled as they are very valuable? And later on discuss the remaining ones?

@hippotastic
Copy link
Copy Markdown
Contributor Author

How about biome?

I actually just did a test right now, I'm still amazed how crazy fast it is and how much easier the configuration is. By turning off only style rules, we get pretty much to the same number of errors as ESLint, altho unfortunately, the errors that started the idea of this PR are not reported yet. Maybe in the future 🤞

Coincidentally I also just did an exploration into Biome! :) I was able to configure it in a way that reports the errors we were looking for. I created #1649 as an alternative to this PR so we can compare.

I think configuration and setup wise, we are pretty much close to the minimum of what we would need. What do you think could be a good next step Hippo? Maybe making a list of all errors reported and figuring out a smaller list of obvious rules we want enabled as they are very valuable? And later on discuss the remaining ones?

My preference would be to decide about the linter to use (ESLint vs Biome), and then go through the errors and actually fix them instead of turning off any further rules. :) In my experience this doesn't take long. Most fixes are straightforward, and there may just be a bit of discussion about how to fix cases in which we have multiple options that all seem to make sense.

@HiDeoo
Copy link
Copy Markdown
Member

HiDeoo commented Mar 20, 2024

I was able to configure it in a way that reports the errors we were looking for.

Ah maybe we are not exactly talking about the exact same error. For me, useAwait only cares about an async function which lacks an await expression.
If we have a test similar to the following one which is reported by both this PR and the biome PR:

test("validates something", async () => {
  expect(async () => await doSomething()).rejects.toThrowError(/invalid/);
});

The big difference for me between useAwait and @typescript-eslint/no-floating-promises is that if my code was instead this one:

test("validates something", async () => {
  await expect(async () => await doSomething1()).rejects.toThrowError(/invalid 1/);
  expect(async () => await doSomething2()).rejects.toThrowError(/invalid 2/);
});

My test does contain an await so useAwait will not report any error. But @typescript-eslint/no-floating-promises will report an error for the second expect call because it is not awaited.

@hippotastic
Copy link
Copy Markdown
Contributor Author

Good catch! Yeah, the no-floating-promises rule doesn't seem to have an equivalent in Biome yet. Also, that the reported issues are not being picked up by GitHub's problem matcher is another downside of Biome right now.

We could just start with ESLint and maybe migrate to Biome once these were fixed?

@HiDeoo
Copy link
Copy Markdown
Member

HiDeoo commented Mar 20, 2024

We could just start with ESLint and maybe migrate to Biome once these were fixed?

I think that's a good approach.

go through the errors and actually fix them instead of turning off any further rules

I personally did not have the time yet to review all the reported errors to make sure they all are real issues in their context as Chris mentioned, make sense for us and would not be too annoying on the long run so if you prefer fixing them all first and we can decide in a later review if we want to disable some rules because the changes are too annoying/not relevant, I'm fine with that 👍

@delucis
Copy link
Copy Markdown
Member

delucis commented Apr 5, 2025

Just a small update to mention that I did not forget about this PR. I still have a local copy of this branch that I update regularly.

Do you want to push that? Or should we close this do you think @HiDeoo? typescript-eslint v8 was released, so I guess we could fix things if we wanted.

@HiDeoo
Copy link
Copy Markdown
Member

HiDeoo commented Apr 7, 2025

Do you want to push that? Or should we close this do you think @HiDeoo? typescript-eslint v8 was released, so I guess we could fix things if we wanted.

I'll update my local branch using a flat config with the latest deps and see where we stand and report back 👍

HiDeoo added 3 commits May 14, 2025 09:28
* main: (151 commits)
  i18n(fr): update slot translation and update Astro Docs links (withastro#3196)
  i18n(ko-KR): update `plugins.mdx` (withastro#3197)
  i18n(fr): update `resources/plugins` (withastro#3195)
  chore(deps): update changesets/action action to v1.5.2 (withastro#3191)
  docs(plugins) Add a link to starlight-scroll-to-top plugin (withastro#3194)
  [ci] format
  docs(showcase): add fluid-dnd showcase (withastro#3193)
  [ci] format
  Cookie API website for Showcase (withastro#3188)
  chore(deps): update changesets/action action to v1.5.1 (withastro#3187)
  [ci] format
  add showcase sonar (withastro#3183)
  [ci] release (withastro#3166)
  Prevent heading anchor links on non-Starlight content (withastro#3181)
  i18n(de): update `css-and-tailwind.mdx` (withastro#3174)
  chore(deps): update changesets/action action to v1.5.0 (withastro#3179)
  i18n(ko-KR): update Korean UI strings (withastro#3168)
  i18n(fr): update `guides/css-and-tailwind.mdx` (withastro#3173)
  i18n(ko-KR): update `css-and-tailwind.mdx` (withastro#3172)
  docs: update Tailwind manual installation instructions (withastro#3170)
  ...
@github-actions github-actions bot added the 📚 docs Documentation website changes label May 14, 2025
@HiDeoo
Copy link
Copy Markdown
Member

HiDeoo commented May 14, 2025

Finally got the time to get back to this PR and update it, sorry for the extra super long delay!

Here is a summary of the changes I made:

  • Updated the branch which was quite old
  • Updated ESLint and all related packages
  • Switched to a flag config
  • Reverted all changes previously made to the PR to ensure some changes due to previous ESLint errors were still relevant now (turns out some of them were not so this was not entirely a huge waste of time ^^)
  • Disabled a bit more rules and entirely commented each config change in the ESLint config
  • Fixed all the remaining and new errors
  • Remove eslint-plugin-no-only-tests as Vitest defaults to error for this on CI and we do the same for Playwright
  • Add the ESLint extension to the recommendations in .vscode/extensions.json

I did not add eslint-plugin-astro as we could do that at a later stage when we have more experience with maintaining the codebase with ESLint being part of it and also at the moment, it does not yet support projectService.

I don't think me updating the branch means "ok, we should merge this" but it's more of a "ok, let's see now what this would look like with everything updated, are we happy with this and all the changes, do we need to disable more rules, etc.". I have been so focused on fixing errors that I also think I need some time to step back and look at all the changes too.

Any feedbacks and opinions are welcome of course.

Copy link
Copy Markdown
Member

@delucis delucis left a comment

Choose a reason for hiding this comment

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

Thanks for updating the PR @HiDeoo! Left a few tiny notes, but didn’t spot anything super major I don’t think.

One question: this doesn’t include eslint-plugin-astro. Is that something you think we should consider too for consistency? (Not essential to include in this PR I don’t think necessarily, unless it might inform a bit more which rules to enable/disable.)

A question for future us would presumably be whether we ever move to Biome for linting and formatting once full Astro support is available, but that could be a way off.

Otherwise, I think I’d find it hard to evaluate the chosen rules too much before actually working with them for a bit to see if any are annoying in practice (I hope not — there aren’t too many instances of code changing or ignore comments in this PR to make me worry) and to get a feel for where it helps catch mistakes. There are definitely some good examples in this PR of where it can help fix and clean things up, so that’s promising.


const i18n = i18next.createInstance();
i18n.init({
void i18n.init({
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.

Is there a rule requiring void for any side-effect function call like this? Seems a bit unnecessary unless there’s an argument for it I’m missing?

(In the past I’ve usually only ever used void in scenarios like () => void fn() to shield the outer function from returning the inner function call’s returned value.)

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 one I need to investigate a bit more, but with typescript-eslint, the void operator is only used here to explicitly mark a Promise as intentionally not awaited. This is the case here as we are explicitly passing it the resources to initialize with and not relying on any loading from the library, which also allows us to keep the entire chain synchronous and avoid having to switch everywhere to await useTranslations() for example.

Depending on where we land at the end, this part will probably need to be updated, at least to comment it, or switch to a different approach.

@HiDeoo
Copy link
Copy Markdown
Member

HiDeoo commented May 20, 2025

One question: this doesn’t include eslint-plugin-astro. Is that something you think we should consider too for consistency? (Not essential to include in this PR I don’t think necessarily, unless it might inform a bit more which rules to enable/disable.)

Indeed, this is something I commented on in this message:

I did not add eslint-plugin-astro as we could do that at a later stage when we have more experience with maintaining the codebase with ESLint being part of it and also at the moment, it does not yet support projectService.

I think it's highly likely that we will need to tweak rules when adding it, but I think it's fine to do that in the future, once we get used to the current setup, maybe refine it based on usage, and maybe once the plugin supports projectService as well (we can use a different approach for that last point but projectService is the new recommended approach by typescript-eslint).

A question for future us would presumably be whether we ever move to Biome for linting and formatting once full Astro support is available, but that could be a way off.

I think that would be the ultimate goal (which was even tested in #1649) but we would indeed need full Astro support and also no-floating-promises as I commended on in this message, as this rule was part of what initially triggered the initiative.

HiDeoo and others added 6 commits August 14, 2025 09:47
* upstream/main: (139 commits)
  chore(deps): update actions/checkout action to v5 (withastro#3375)
  Disable Renovate `uses-with` for Node.js (withastro#3376)
  i18n(fr): update `resources/plugins` (withastro#3378)
  chore(deps): update github-actions (withastro#3374)
  i18n(ko-KR): update `plugins.mdx` (withastro#3377)
  i18n(de): update `plugins.mdx` (withastro#3367)
  Add `starlight-github-alerts` plugin to plugin showcase (withastro#3369)
  i18n(fr): update `resources/plugins.mdx` (withastro#3372)
  i18n(fr): update `resources/community-content.mdx` (withastro#3371)
  [ci] format
  i18n(fr): update `environmental-impact.md` (withastro#3370)
  [ci] format
  i18n(de): update `community-content.mdx` (withastro#3366)
  [ci] format
  i18n(de): update `environmental-impact.md` (withastro#3365)
  [ci] format
  i18n(ko-KR): update `environmental-impact.md` (withastro#3368)
  Update carbon calculator stats for v4 model (withastro#3364)
  i18n(ko-KR): update `community-content.mdx` (withastro#3362)
  i18n(ko-KR): update `plugins.mdx` (withastro#3361)
  ...
Co-authored-by: delucis <357379+delucis@users.noreply.github.com>
@HiDeoo
Copy link
Copy Markdown
Member

HiDeoo commented Aug 14, 2025

Just updated the PR, updated some new dependencies introduced in this PR, fixed the new issues following the branch update, and addressed the last review (the most notable change is createTranslationSystem now being async as my assumption about i18n.init() was based on older i18next versions and no longer valid).

@HiDeoo HiDeoo marked this pull request as ready for review August 14, 2025 09:26
Copy link
Copy Markdown
Member

@delucis delucis left a comment

Choose a reason for hiding this comment

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

I only spotted a typo! And then… ready to merge? 😱

Do you think we should have a patch changeset just so we note the refactor in changelogs in case we ever want to trace back to this PR?

The createTranslationSystem one is an interesting one, but should be fine, I think. We have occasionally seen weird bundling issues with top-level await for some users in the past, but with any luck this one doesn’t cause any trouble 👍

HiDeoo and others added 2 commits August 19, 2025 09:06
Co-authored-by: delucis <357379+delucis@users.noreply.github.com>
@delucis delucis added the 🌟 patch Change that triggers a patch release label Aug 19, 2025
Copy link
Copy Markdown
Member

@delucis delucis left a comment

Choose a reason for hiding this comment

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

Changeset looks good! I think the time has come.

Thanks @hippotastic for kicking this off in the distant mists of time and to @HiDeoo for forging ahead to take us to the promised lint.

See you in 6 months when we rewrite it to use Biome 😁

@delucis delucis merged commit d1b3828 into withastro:main Aug 19, 2025
17 checks passed
@astrobot-houston astrobot-houston mentioned this pull request Aug 19, 2025
@hippotastic
Copy link
Copy Markdown
Contributor Author

Thanks @hippotastic for kicking this off in the distant mists of time and to @HiDeoo for forging ahead to take us to the promised lint.

See you in 6 months when we rewrite it to use Biome 😁

Hahaha, I just checked the date when I first opened this - it really has been a while! Amazing to see how the rough 4-day draft turned into such a solid setup. Huge thanks to @HiDeoo for taking the torch and shaping it into something that truly fits Starlight's codebase.

Can't wait for noFloatingPromises to leave Biome V2's nursery group, then we might actually finally revisit #1649. 😄 And given the solid setup we now have thanks to you, it hopefully won't take another year.

@hippotastic hippotastic deleted the add-eslint branch August 19, 2025 08:45
trueberryless pushed a commit to trueberryless/withastro-starlight that referenced this pull request Aug 19, 2025
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
Co-authored-by: HiDeoo <494699+HiDeoo@users.noreply.github.com>
Co-authored-by: delucis <357379+delucis@users.noreply.github.com>
HiDeoo added a commit to HiDeoo/starlight that referenced this pull request Aug 26, 2025
* main: (55 commits)
  i18n(de): translate `themes.mdx` (withastro#3397)
  [ci] format
  i18n(ko): translate `themes.mdx` (withastro#3398)
  [ci] format
  docs: add Starlight Page to themes showcase (withastro#3393)
  i18n(de): update German themes (withastro#3394)
  docs: change image of Starlight Galaxy Theme dark image to not include a visible scrollbar (withastro#3395)
  [ci] format
  i18n(ko-KR): update `themes.mdx` (withastro#3392)
  [ci] format
  Add link to new Starlight theme (withastro#3390)
  i18n(fr): update `guides/css-and-tailwind.mdx` (withastro#3389)
  i18n(de): translate `guides/css-and-tailwind.mdx` (withastro#3386)
  [ci] format
  i18n(ko-KR): update `css-and-tailwind.mdx` (withastro#3388)
  Adds OmniPrint documentation to the showcase (withastro#3387)
  docs(showcase): Add Aptos Docs (withastro#3385)
  docs: add section about multiple Tailwind configs (withastro#3273)
  Add basic ESLint config, lint script and lint CI job (withastro#1640)
  chore(deps): update actions/checkout action to v5 (withastro#3375)
  ...
HiDeoo added a commit to HiDeoo/starlight that referenced this pull request Aug 27, 2025
* main: (137 commits)
  i18n(fr): update `resources/themes.mdx` (withastro#3399)
  i18n(de): translate `themes.mdx` (withastro#3397)
  [ci] format
  i18n(ko): translate `themes.mdx` (withastro#3398)
  [ci] format
  docs: add Starlight Page to themes showcase (withastro#3393)
  i18n(de): update German themes (withastro#3394)
  docs: change image of Starlight Galaxy Theme dark image to not include a visible scrollbar (withastro#3395)
  [ci] format
  i18n(ko-KR): update `themes.mdx` (withastro#3392)
  [ci] format
  Add link to new Starlight theme (withastro#3390)
  i18n(fr): update `guides/css-and-tailwind.mdx` (withastro#3389)
  i18n(de): translate `guides/css-and-tailwind.mdx` (withastro#3386)
  [ci] format
  i18n(ko-KR): update `css-and-tailwind.mdx` (withastro#3388)
  Adds OmniPrint documentation to the showcase (withastro#3387)
  docs(showcase): Add Aptos Docs (withastro#3385)
  docs: add section about multiple Tailwind configs (withastro#3273)
  Add basic ESLint config, lint script and lint CI job (withastro#1640)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🚨 action Changes to GitHub Action workflows 🌟 core Changes to Starlight’s main package 📚 docs Documentation website changes 🌟 patch Change that triggers a patch release 🌟 tailwind Changes to Starlight’s Tailwind package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants