# Comments

> Stop writing so many comments. Follow these suggestions instead!

- Skill: `ledgerhq/comments` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ledgerhq/comments`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ledgerhq/comments/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ledgerhq (https://skillmd.com/u/ledgerhq)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ledgerhq/comments

---


# Comments in code

## 🧀 Avoid comments

Comments are _code smells_ because they go out-of-date, bloat context, and lead to confusion.

**Don't reference existing comments in the codebase – follow these rules**

- **Avoid adding comments** – always prefer good names (explainer variables, functions, tests)
- **Use test names to describe behaviour** – unit tests are living documentation
- **Good code explains itself** – don't add comments that duplicate what the code already conveys

## 💡 Treatments

When code isn't clear, make it clearer:

- Rename variables and functions to make comments unnecessary
- Extract variables and functions to improve readability
- Use assertions to explain behaviour

### Use test names to explain non-obvious details

**❌ Bad**

```ts
it("diffs the current value against resolved when targeted", () => {
  const { result } = renderHook(() => useJsonEditor(makeProps()));
  act(() => result.current.setDiffTarget("resolved"));
  // Current equals resolved → every line is unchanged.
  expect(result.current.diffJson.every((l) => l.state === "none")).toBe(true);
});
```

**✅ Good**

```ts
it("resets the state of every line when the diff is resolved", () => {
  const { result } = renderHook(() => useJsonEditor(makeProps()));
  act(() => result.current.setDiffTarget("resolved"));
  expect(result.current.diffJson.every((l) => l.state === "none")).toBe(true);
});
```

### Let code speak for itself

**❌ Bad**

```ts
/* Whether the filter trigger should be displayed */
showFilter: boolean;
```

**✅ Good**

```ts
showFilter: boolean;
```

### Replace comments with explainer variables

Move the comment into a variable name:

**Before**

```ts
// NB `app.trustchain` is an encrypted db path: while the app is password-locked it reads back
// as the ciphertext string. Importing it would regenerate member credentials and null the
// trustchain (LIVE-36130). IsUnlocked re-runs this thunk once the encryption key is set.
// `undefined` must still go through: that is the legitimate "nothing persisted" case.
if (typeof data === "string") return;
```

**After**

```ts
const dataIsEncrypted = typeof data === "string";
if (dataIsEncrypted) return;
```

## ☝️ When comments are necessary

Comments are only for vital information that can't go anywhere else. **Always prefer not adding comments.** If a comment is the only way, follow these guidelines:

- **Be concise**: Use as few words as possible to convey the necessary information.
- **Use JSDocs**: Only when describing a shared function.
- **Prefer a link**: If the comment is explaining a workaround for a known issue, link to the issue or docs.

**❌ Bad**

```yaml
# pnpm patches add 'patch_hash=HASH' to virtual store paths, which prefab 2.1.0
# (introduced via AGP 8.11) misparses as an option flag due to a clikt bug that splits
# positional path arguments at '='. Pinning prefab to 2.0.0 in gradle.properties avoids
# this; keeping path segments ≤ 80 chars shortens virtual-store paths to reduce the
# likelihood of triggering prefab path-parsing issues as an additional safeguard.
android.prefab.version=2.0.0
virtual-store-dir-max-length=80
```

**✅ Better**

```yaml
# Workaround for Prefab 2.1.0/Clikt bug
# See: https://github.com/google/prefab/issues/187
android.prefab.version=2.0.0
virtual-store-dir-max-length=80
```

