AphrodyBun GitHub

Runtime docs · Linter · Rules

no-underscore-dangle

Disallow names that start or end with an underscore

A leading or trailing underscore is a convention for "private", but it doesn't protect anything. Any code can still read and write user._id. If a member needs to be private, use a #private class member, which the language enforces.

By default the rule checks variable and function declarations and property access. It doesn't check parameters, destructured names, or method and class field names where they're defined. The name _ alone and obj.__proto__ are always allowed.

Configure

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"no-underscore-dangle" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"no-underscore-dangle" = ["error", {
  allow = [], # list of strings
  allowAfterThis = false,
  allowAfterSuper = false,
  allowAfterThisConstructor = false,
  allowFunctionParams = true,
  allowInArrayDestructuring = true,
  allowInObjectDestructuring = true,
  enforceInMethodNames = false,
  enforceInClassFields = false,
}]

Examples

Reported:

const _cache = new Map();

function load_(id) {
  return user._id === id;
}

Not reported:

const cache = new Map();

function load(_request, id) {
  const [_first, second] = id.split("-");
  return _.isEqual(second, user.id);
}

Options

OptionDefaultWhat it does
allow[]Names that are never reported.
allowAfterThisfalseAllow this._name.
allowAfterSuperfalseAllow super._name.
allowAfterThisConstructorfalseAllow this.constructor._name.
allowFunctionParamstrueAllow function f(_a) {}.
allowInArrayDestructuringtrueAllow const [_a] = list.
allowInObjectDestructuringtrueAllow const { _a } = obj.
enforceInMethodNamesfalseAlso report method names, in classes and in object literals.
enforceInClassFieldsfalseAlso report class field names.

An oxlint config has one more option. allowInUsingDeclarations (default false) allows using _lock = acquire().

bunfig.toml
[lint.rules]
no-underscore-dangle = ["error", { allow = ["_id"], allowAfterThis = true }]
class Store {
  find(doc) {
    return this._items.get(doc._id);
  }
}

enforceInMethodNames and enforceInClassFields also apply to private members such as #_count:

class Store {
  _items = new Map();
  #_count = 0;

  _reset() {}
}
function onClick(_event) {
  close();
}

When not to use it

Turn it off if your project uses _name for unused variables or for members that are internal by agreement.