{"id":13459271,"url":"https://github.com/kettanaito/naming-cheatsheet","last_synced_at":"2025-05-13T20:22:37.678Z","repository":{"id":37286644,"uuid":"95863194","full_name":"kettanaito/naming-cheatsheet","owner":"kettanaito","description":"Comprehensive language-agnostic guidelines on variables naming. Home of the A/HC/LC pattern.","archived":false,"fork":false,"pushed_at":"2024-03-13T22:39:17.000Z","size":56,"stargazers_count":14087,"open_issues_count":24,"forks_count":927,"subscribers_count":114,"default_branch":"main","last_synced_at":"2025-05-07T07:21:15.395Z","etag":null,"topics":["action","cheatsheet","guideline","guidelines","high-context","low-context","naming","naming-cheatsheet","naming-conventions","naming-pattern","naming-schemes","pattern","prefix","variables"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kettanaito.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":"kettanaito"}},"created_at":"2017-06-30T07:46:04.000Z","updated_at":"2025-05-07T07:03:02.000Z","dependencies_parsed_at":"2022-07-09T11:16:06.805Z","dependency_job_id":"aed0082f-d449-40ae-aaa9-fa652297ad27","html_url":"https://github.com/kettanaito/naming-cheatsheet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kettanaito%2Fnaming-cheatsheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kettanaito%2Fnaming-cheatsheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kettanaito%2Fnaming-cheatsheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kettanaito%2Fnaming-cheatsheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kettanaito","download_url":"https://codeload.github.com/kettanaito/naming-cheatsheet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253594588,"owners_count":21933247,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["action","cheatsheet","guideline","guidelines","high-context","low-context","naming","naming-cheatsheet","naming-conventions","naming-pattern","naming-schemes","pattern","prefix","variables"],"created_at":"2024-07-31T09:01:13.411Z","updated_at":"2025-05-13T20:22:37.619Z","avatar_url":"https://github.com/kettanaito.png","language":null,"funding_links":["https://github.com/sponsors/kettanaito"],"categories":["miscellaneous","Others","0. Basics","others","📦 Legacy \u0026 Inactive Projects"],"sub_categories":["0.3. Code OCD"],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/kettanaito/naming-cheatsheet\"\u003e\n    \u003cimg src=\"./naming-cheatsheet.png\" alt=\"Naming cheatsheet\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# Naming cheatsheet\n\n- [English language](#english-language)\n- [Naming convention](#naming-convention)\n- [S-I-D](#s-i-d)\n- [Avoid contractions](#avoid-contractions)\n- [Avoid context duplication](#avoid-context-duplication)\n- [Reflect the expected result](#reflect-the-expected-result)\n- [Naming functions](#naming-functions)\n  - [A/HC/LC pattern](#ahclc-pattern)\n    - [Actions](#actions)\n    - [Context](#context)\n    - [Prefixes](#prefixes)\n- [Singular and Plurals](#singular-and-plurals)\n\n---\n\nNaming things is hard. This sheet attempts to make it easier.\n\nAlthough these suggestions can be applied to any programming language, I will use JavaScript to illustrate them in practice.\n\n## English language\n\nUse English language when naming your variables and functions.\n\n```js\n/* Bad */\nconst primerNombre = 'Gustavo'\nconst amigos = ['Kate', 'John']\n\n/* Good */\nconst firstName = 'Gustavo'\nconst friends = ['Kate', 'John']\n```\n\n\u003e Like it or not, English is the dominant language in programming: the syntax of all programming languages is written in English, as well as countless documentations and educational materials. By writing your code in English you dramatically increase its cohesiveness.\n\n## Naming convention\n\nPick **one** naming convention and follow it. It may be `camelCase`, `PascalCase`, `snake_case`, or anything else, as long as it remains consistent. Many programming languages have their own traditions regarding naming conventions; check the documentation for your language or study some popular repositories on GitHub!\n\n```js\n/* Bad */\nconst page_count = 5\nconst shouldUpdate = true\n\n/* Good */\nconst pageCount = 5\nconst shouldUpdate = true\n\n/* Good as well */\nconst page_count = 5\nconst should_update = true\n```\n\n## S-I-D\n\nA name must be _short_, _intuitive_ and _descriptive_:\n\n- **Short**. A name must not take long to type and, therefore, remember;\n- **Intuitive**. A name must read naturally, as close to the common speech as possible;\n- **Descriptive**. A name must reflect what it does/possesses in the most efficient way.\n\n```js\n/* Bad */\nconst a = 5 // \"a\" could mean anything\nconst isPaginatable = a \u003e 10 // \"Paginatable\" sounds extremely unnatural\nconst shouldPaginatize = a \u003e 10 // Made up verbs are so much fun!\n\n/* Good */\nconst postCount = 5\nconst hasPagination = postCount \u003e 10\nconst shouldPaginate = postCount \u003e 10 // alternatively\n```\n\n## Avoid contractions\n\nDo **not** use contractions. They contribute to nothing but decreased readability of the code. Finding a short, descriptive name may be hard, but contraction is not an excuse for not doing so.\n\n```js\n/* Bad */\nconst onItmClk = () =\u003e {}\n\n/* Good */\nconst onItemClick = () =\u003e {}\n```\n\n## Avoid context duplication\n\nA name should not duplicate the context in which it is defined. Always remove the context from a name if that doesn't decrease its readability.\n\n```js\nclass MenuItem {\n  /* Method name duplicates the context (which is \"MenuItem\") */\n  handleMenuItemClick = (event) =\u003e { ... }\n\n  /* Reads nicely as `MenuItem.handleClick()` */\n  handleClick = (event) =\u003e { ... }\n}\n```\n\n## Reflect the expected result\n\nA name should reflect the expected result.\n\n```jsx\n/* Bad */\nconst isEnabled = itemCount \u003e 3\nreturn \u003cButton disabled={!isEnabled} /\u003e\n\n/* Good */\nconst isDisabled = itemCount \u003c= 3\nreturn \u003cButton disabled={isDisabled} /\u003e\n```\n\n---\n\n# Naming functions\n\n## A/HC/LC Pattern\n\nThere is a useful pattern to follow when naming functions:\n\n```\nprefix? + action (A) + high context (HC) + low context? (LC)\n```\n\nTake a look at how this pattern may be applied in the table below.\n\n| Name                   | Prefix   | Action (A) | High context (HC) | Low context (LC) |\n| ---------------------- | -------- | ---------- | ----------------- | ---------------- |\n| `getUser`              |          | `get`      | `User`            |                  |\n| `getUserMessages`      |          | `get`      | `User`            | `Messages`       |\n| `handleClickOutside`   |          | `handle`   | `Click`           | `Outside`        |\n| `shouldDisplayMessage` | `should` | `Display`  | `Message`         |                  |\n\n\u003e **Note:** The order of context affects the meaning of a variable. For example, `shouldUpdateComponent` means _you_ are about to update a component, while `shouldComponentUpdate` tells you that _component_ will update itself, and you are only controlling _when_ it should update.\n\u003e In other words, **high context emphasizes the meaning of a variable**.\n\n---\n\n## Actions\n\nThe verb part of your function name. The most important part responsible for describing what the function _does_.\n\n### `get`\n\nAccesses data immediately (i.e. shorthand getter of internal data).\n\n```js\nfunction getFruitCount() {\n  return this.fruits.length\n}\n```\n\n\u003e See also [compose](#compose).\n\nYou can use `get` when performing asynchronous operations as well:\n\n```js\nasync function getUser(id) {\n  const user = await fetch(`/api/user/${id}`)\n  return user\n}\n```\n\n### `set`\n\nSets a variable in a declarative way, with value `A` to value `B`.\n\n```js\nlet fruits = 0\n\nfunction setFruits(nextFruits) {\n  fruits = nextFruits\n}\n\nsetFruits(5)\nconsole.log(fruits) // 5\n```\n\n### `reset`\n\nSets a variable back to its initial value or state.\n\n```js\nconst initialFruits = 5\nlet fruits = initialFruits\nsetFruits(10)\nconsole.log(fruits) // 10\n\nfunction resetFruits() {\n  fruits = initialFruits\n}\n\nresetFruits()\nconsole.log(fruits) // 5\n```\n\n### `remove`\n\nRemoves something _from_ somewhere.\n\nFor example, if you have a collection of selected filters on a search page, removing one of them from the collection is `removeFilter`, **not** `deleteFilter` (and this is how you would naturally say it in English as well):\n\n```js\nfunction removeFilter(filterName, filters) {\n  return filters.filter((name) =\u003e name !== filterName)\n}\n\nconst selectedFilters = ['price', 'availability', 'size']\nremoveFilter('price', selectedFilters)\n```\n\n\u003e See also [delete](#delete).\n\n### `delete`\n\nCompletely erases something from the realms of existence.\n\nImagine you are a content editor, and there is that notorious post you wish to get rid of. Once you clicked a shiny \"Delete post\" button, the CMS performed a `deletePost` action, **not** `removePost`.\n\n```js\nfunction deletePost(id) {\n  return database.find({ id }).delete()\n}\n```\n\n\u003e See also [remove](#remove).\n\n\u003e **`remove` or `delete`?**\n\u003e\n\u003e When the difference between `remove` and `delete` is not so obvious to you, I'd suggest looking at their opposite actions - `add` and `create`.\n\u003e The key difference between `add` and `create` is that `add` needs a destination while `create` **requires no destination**. You `add` an item _to somewhere_, but you don't \"`create` it _to somewhere_\".\n\u003e Simply pair `remove` with `add` and `delete` with `create`.\n\u003e\n\u003e Explained in detail [here](https://github.com/kettanaito/naming-cheatsheet/issues/74#issue-1174942962).\n\n### `compose`\n\nCreates new data from the existing one. Mostly applicable to strings, objects, or functions.\n\n```js\nfunction composePageUrl(pageName, pageId) {\n  return pageName.toLowerCase() + '-' + pageId\n}\n```\n\n\u003e See also [get](#get).\n\n### `handle`\n\nHandles an action. Often used when naming a callback method.\n\n```js\nfunction handleLinkClick() {\n  console.log('Clicked a link!')\n}\n\nlink.addEventListener('click', handleLinkClick)\n```\n\n---\n\n## Context\n\nA domain that a function operates on.\n\nA function is often an action on _something_. It is important to state what its operable domain is, or at least an expected data type.\n\n```js\n/* A pure function operating with primitives */\nfunction filter(list, predicate) {\n  return list.filter(predicate)\n}\n\n/* Function operating exactly on posts */\nfunction getRecentPosts(posts) {\n  return filter(posts, (post) =\u003e post.date === Date.now())\n}\n```\n\n\u003e Some language-specific assumptions may allow omitting the context. For example, in JavaScript, it's common that `filter` operates on Array. Adding explicit `filterArray` would be unnecessary.\n\n---\n\n## Prefixes\n\nPrefix enhances the meaning of a variable. It is rarely used in function names.\n\n### `is`\n\nDescribes a characteristic or state of the current context (usually `boolean`).\n\n```js\nconst color = 'blue'\nconst isBlue = color === 'blue' // characteristic\nconst isPresent = true // state\n\nif (isBlue \u0026\u0026 isPresent) {\n  console.log('Blue is present!')\n}\n```\n\n### `has`\n\nDescribes whether the current context possesses a certain value or state (usually `boolean`).\n\n```js\n/* Bad */\nconst isProductsExist = productsCount \u003e 0\nconst areProductsPresent = productsCount \u003e 0\n\n/* Good */\nconst hasProducts = productsCount \u003e 0\n```\n\n### `should`\n\nReflects a positive conditional statement (usually `boolean`) coupled with a certain action.\n\n```js\nfunction shouldUpdateUrl(url, expectedUrl) {\n  return url !== expectedUrl\n}\n```\n\n### `min`/`max`\n\nRepresents a minimum or maximum value. Used when describing boundaries or limits.\n\n```js\n/**\n * Renders a random amount of posts within\n * the given min/max boundaries.\n */\nfunction renderPosts(posts, minPosts, maxPosts) {\n  return posts.slice(0, randomBetween(minPosts, maxPosts))\n}\n```\n\n### `prev`/`next`\n\nIndicate the previous or the next state of a variable in the current context. Used when describing state transitions.\n\n```jsx\nasync function getPosts() {\n  const prevPosts = this.state.posts\n\n  const latestPosts = await fetch('...')\n  const nextPosts = concat(prevPosts, latestPosts)\n\n  this.setState({ posts: nextPosts })\n}\n```\n\n## Singular and Plurals\n\nLike a prefix, variable names can be made singular or plural depending on whether they hold a single value or multiple values.\n\n```js\n/* Bad */\nconst friends = 'Bob'\nconst friend = ['Bob', 'Tony', 'Tanya']\n\n/* Good */\nconst friend = 'Bob'\nconst friends = ['Bob', 'Tony', 'Tanya']\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkettanaito%2Fnaming-cheatsheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkettanaito%2Fnaming-cheatsheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkettanaito%2Fnaming-cheatsheet/lists"}