Skip to content

AI front end code review guidelines and claude skills#1292

Merged
labkey-martyp merged 7 commits intodevelopfrom
fb_frontend_code_review_skills
Mar 4, 2026
Merged

AI front end code review guidelines and claude skills#1292
labkey-martyp merged 7 commits intodevelopfrom
fb_frontend_code_review_skills

Conversation

@labkey-martyp
Copy link
Contributor

@labkey-martyp labkey-martyp commented Feb 23, 2026

Rationale

This is a starting point for frontend ai code review guidelines. There are two code review checklists and claude skills, /code-review-react and /code-review-jest. The claude skills have two modes,

  1. Review only staged changes (changes not committed yet). ex. /code-review-react <directory or file path>
  2. Review full files or directories. ex /code-review-jest --full <directory or file path>
  • See .agents/common.md for review priority and format.
  • See the "Required output" section of the .claude/skills/<skill name>/skill.md for the expected output. Note: If there are more than 10 "suggested" changes (non-urgent), only the first 10 will be shown in each run.
  • See the files in .agents/review-checklists/<react or jest>/*.md for the code review checks.

It is recommended to run the code reviews multiple times until all the feedback is addressed.

These guidelines can be used by other ai agents as well, just point them to the directory.

Changes

  • .agents/review-checklists/jest code review checks
  • .agents/review-checklists/react code review checks
  • .agents/review-checkslists/common.md general code review guidelines
  • .claude/skill/<skill name>/skill.md define the claude skill using these guidelines

Copy link
Contributor

@labkey-jeckels labkey-jeckels left a comment

Choose a reason for hiding this comment

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

I don't have React or Jest changes handy to test this out, but the overall structure seems reasonable.

Others can better comment on whether these are the right items to highlight, but this might be best evaluated through actual testing.

I can see pulling some of this guidance into more general areas in the future. For example, the rules for code comments should be applicable to any language, not just React/TypeScript/JavaScript.

Copy link
Contributor

@cnathe cnathe left a comment

Choose a reason for hiding this comment

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

I left some comments but I agree that this will need to be treated as a working document as we use it and until we start using it, it is hard to know exactly what we all want here. Looks like a great starting point.

4. Compose the review section per the template below. Group findings by **Urgency** section first (urgent issues, then suggestions). Within each section, order findings by the checklist primary category priority: **Correctness**, then **Maintainability**, then **Style**.

## Required output
When invoked, the response must exactly follow one of the two templates:
Copy link
Contributor

Choose a reason for hiding this comment

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

so much of the text / instructions above this line in this file are so close to a duplicate of the code-review-react/skill.md file. This likely makes sense as there might not be a good way to share that part of these instructions. I'm just a little worried about how we are goign to keep these things up to date and in sync.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah good call. I think some of this can be combined. I will look into doing that in a follow up PR.


### Confidence Threshold

Flag when the symbol is clearly unused in the file or when a mock setup is not consumed by behavior under test. If a mock or import may be used implicitly (module mocking side effects, global setup conventions), verify before commenting.
Copy link
Contributor

Choose a reason for hiding this comment

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

what does "the symbol" mean in this sentence? do you mean variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it kind of applies to variables, imports or mock setups. I'm not sure if there's more appropriate terminology?

6. **Unused parameters in callbacks must be prefixed with `_`.** If a callback parameter (e.g., in `.mockImplementation((unusedArg) => ...)`) is required for positional reasons but not used, prefix it with `_` to signal intent (e.g., `_unusedArg`).
7. **Unused `render` results must not be destructured.** If `render(<Component />)` is called and the return value is not used, do not destructure it. Write `render(<Component />);` instead of `const { container } = render(<Component />);` when `container` is never referenced.

### Examples
Copy link
Contributor

Choose a reason for hiding this comment

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

this is great. I'd love to not have to manually check as a code reviewer if the import or variable is used!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I think these kinds of things can save us time on code reviews so we can spend more time on higher level thinking.


> **Prerequisite:** Review and apply the common guidelines in [`common.md`](../common.md) before using this checklist.

## No redundant or near-duplicate tests
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious what AI would consider a near-duplicate test. I think using near duplicate tests is exactly how test cases often look when you are testing interactions of a sequence of parameters or properties (i.e. adjust prop1, then prop2, then prop3, etc. but the test is nearly the same).

Copy link
Contributor

Choose a reason for hiding this comment

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

So, in those cases we should be using something like jest.each, where we have one shared test body, but you parametrize the test with an array of args. We don't do this a lot right now, but we should for sure be doing it more.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah maybe "redundant" and "near-duplicate" should be split into separate checks. One is performance - not running redundant tests, the other may be more code-quality - sharing common code and using test.each (see example)


// ✅ Fallback for optional props
const [text, setText] = useState(props.initialText ?? '');
```
Copy link
Contributor

Choose a reason for hiding this comment

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

this is great. these are always tough things to catch when manually scrolling through a large PR code change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah these can be annoying to debug

};
```

## Optional props that are always passed should be required
Copy link
Contributor

Choose a reason for hiding this comment

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

this one has been debated a few times before by the Frontend group and I think people fall on different camps here. Seems fine to include as long as we are making an effort to be sure to update / adjust this set of rules as we work through usages.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this has been debated. I'm the one who has brought this to the group multiple times, basically anytime I've encountered an issue caused by this, or when I've done large refactors and discovered multiple type related issues, and I don't recall a time that I have gotten push back on this. The upside is that by following this rule your types are more correct, and it eliminates a whole class of bug, the downside is that it's slightly more verbose.

- **CSS Modules:** When using CSS Modules (`.module.css` / `.module.scss`), camelCase class names are standard since they become JS property names (e.g., `styles.searchForm`, `styles.activeItem`). Do not flag these as BEM violations.
- **Existing non-BEM code:** Class names in unchanged code that predate BEM adoption should not be flagged. Only apply BEM conventions to new or actively modified class names in the PR.

## No orphaned or unused CSS/SCSS rules
Copy link
Contributor

Choose a reason for hiding this comment

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

this would be great if AI can help with this one! this is very tedious to track down manually

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it absolutely can. So much easier than doing it manually

Copy link
Contributor

@labkey-alan labkey-alan left a comment

Choose a reason for hiding this comment

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

I think overall these rules are fine. I did leave some feedback that you should review before merging. If you have follow up questions, or want to have a discussion, let me know.

My biggest issue with these rules at the moment is that I don't really think this is the appropriate place for them, as this keeps them scoped to LabKey server and modules defined within it, but it excludes their availability to our packages e.g. labkey-ui-components, labkey-ui-premium, which is where the majority of our react and jest code lives. I also don't really want a solution that involves duplicating these rules across every repo that needs them. That said, I think this is an acceptable place to put them for now, as it allows people to experiment with them today, albeit in a limited scope. We can always move these rules to a more ideal location later.

### Exceptions / False Positives

- Allow explicit smoke tests when the purpose is only to verify the component/function does not throw on render or initialization.
- Do not flag helper tests that intentionally validate test utilities/builders rather than product behavior, if the subject under test is the utility itself.
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure I understand this rule. Are we ever testing our test utilities?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed it. I think it would be applicable if we were specifically testing our API wrapper framework or something, but probably not doing that anywhere.

expect(data[0].name).toBe('Alpha'); // This tests your test, not your code

// ✅ GOOD — asserts on rendered output from that input
const data = [{ name: 'Alpha', value: 10 }];
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 we should encourage even more specific checks here. I think keeping this section is good, but maybe adding something that says "instead of looking for the existence of data anywhere, look for the existence of data where it is expected to be". Then provide an example of looking for "name" to be in the first column of the example Table component here, or something similar. Just generically looking for content to be on the page may be so overbroad that it is not useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I added a more specific example.


- Do not flag short tests (roughly 3-5 lines) where Arrange/Act/Assert is obvious without comments.
- Do not require AAA comments in parameterized tests when added comments make the test harder to scan than the code itself.
- Prefer suggestions over high-severity findings unless the repository explicitly enforces AAA comment structure in tests.
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure this is useful, since we don't have any repositories where AAA comments are explicitly enforced, and most of our existing tests do not follow this pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I found it really useful to at least have the Assert part with a comment on how it is asserting what is being tested. Some structure and consistency is helpful as well. But I'm not set on AAA, it's just what I found when researching ways to have test clarity for people and AI.


### Confidence Threshold

Flag as a high-severity finding when a nested function is used as a React component type (capitalized and rendered with JSX) inside a component body, causing remounts and state loss. Do not confuse this with render helpers that return JSX but are not treated as component types.
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 we should consider a rule that discourages render helpers. We have relied on them a ton in the past, but not in helpful ways. 99/100 render helpers at LabKey should be components.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you point me to an example or two in our code? We can get that in a follow up PR.

@labkey-martyp
Copy link
Contributor Author

I think overall these rules are fine. I did leave some feedback that you should review before merging. If you have follow up questions, or want to have a discussion, let me know.

My biggest issue with these rules at the moment is that I don't really think this is the appropriate place for them, as this keeps them scoped to LabKey server and modules defined within it, but it excludes their availability to our packages e.g. labkey-ui-components, labkey-ui-premium, which is where the majority of our react and jest code lives. I also don't really want a solution that involves duplicating these rules across every repo that needs them. That said, I think this is an acceptable place to put them for now, as it allows people to experiment with them today, albeit in a limited scope. We can always move these rules to a more ideal location later.

Yep it would be great to discuss a better location. I actually thought everyone was putting labkey-ui-components and labkey-ui-premium under server, but from our meeting I now realize that is not the case.

@labkey-martyp labkey-martyp merged commit 7605253 into develop Mar 4, 2026
6 of 7 checks passed
@labkey-martyp labkey-martyp deleted the fb_frontend_code_review_skills branch March 4, 2026 10:37
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