How to Write Readable JavaScript Code: Tips for Clean, Maintainable Code

The article explains why readable code matters, shows a messy JavaScript example, lists common readability problems, and provides concrete guidelines—consistent style, meaningful naming, proper comments, small files, shallow nesting—along with tooling tips such as ESLint, Standard Style, husky and lint‑staged to enforce them.

Tencent Cloud Developer
Tencent Cloud Developer
Tencent Cloud Developer
How to Write Readable JavaScript Code: Tips for Clean, Maintainable Code

Readable code significantly improves development efficiency because developers spend a large portion of their time reading existing code. Unreadable code leads to frustration and bugs.

Problematic Example

const user = ...
const foo = (cb) => ...
const bar = (list, cb) => ...
const other = (list1, list2) => ...

if (user ? user.isAdmin : ((user.permission && user.permission.view) ? user.permission.view === true : false)) {
  foo((res) => {
    if (res && res.ok && res.list && res.list.length > 0) {
      bar(res.list, (res2) => {
        if (res2 && res2.ok && res2.list && res2.list.length > 0) {
          other(res.list, res2.list)
        }
      })
    }
  })
}

Issues in this snippet include mismatched function names, overly complex conditional logic, and deep callback nesting.

Refactored, Readable Version

const user = ...
const fetchChannel = () => ...
const fetchArticle = (list) => ...
const render = (channelList, articleList) => ...

const hasViewPermission = user.isAdmin || user.permission?.view
if (!hasViewPermission) {
  return
}

const { ok, list: channelList } = await fetchChannel()
if (!(ok && channelList?.length > 0)) {
  return
}

const { ok: fetchArticleOk, articleList } = await fetchArticle(channelList)
if (!(fetchArticleOk && articleList.length > 0)) {
  return
}

render(channelList, articleList)

The refactored code uses clear naming, early returns, async/await, and eliminates nested callbacks.

Key Characteristics of Readable Code

Consistent code style (spacing, indentation, naming conventions) across the project.

Meaningful names that convey intent.

Comments that explain *why* something is done, not merely *what* the code does.

Small, focused files (avoid files > 1000 lines).

Shallow nesting of control structures and function calls.

1. Consistent Code Style

Adopt a unified style guide such as the Airbnb JavaScript Style Guide or JavaScript Standard Style. The Standard Style requires no configuration and can be applied with: npx standard --fix Enforce the style with ESLint (https://eslint.org). For pre‑commit checks, combine husky (https://www.npmjs.com/package/husky) with lint‑staged (https://www.npmjs.com/package/lint-staged) to lint only the files changed in a commit.

2. Meaningful Naming

Use explicit names (e.g., fetchUserInfo instead of foo or bar). Follow common conventions: id for identifiers, short loop counters ( i, j, k), and project‑specific case style (camelCase, kebab‑case, etc.).

Bad vs. Good Naming Example

// bad
async function getUserName(userId) {
  const userName = await fetchUser(userId)
  return userName
}

// good
async function getUserName(id) {
  const name = await fetchUser(id)
  return name
}

3. Purposeful Comments

Write comments only when the code does not clearly express the author's intent or when the logic is complex. Avoid comments that merely restate the code.

4. Keep Files Small

Large files (e.g., >1000 lines) usually indicate multiple responsibilities. Use ESLint’s max‑lines rule to detect them and split functionality into separate modules.

5. Avoid Deep Nesting

Replace callback hell with async/await or helper functions. Use early returns to flatten if chains. Example of callback hell:

fetchData1(data1 => {
  fetchData2(data2 => {
    fetchData3(data3 => {
      done(data1, data2, data3)
    })
  })
})

Example of deep if nesting:

if (isEvenNum(num)) {
  if (isBetween(num)) {
    if (isDivisible(num)) {
      return true
    }
    return false
  }
  return false
}
return false

In React, excessive higher‑order component (HOC) or Context nesting can be mitigated by composition patterns or hooks.

Additional Recommendations

Limit the number of function parameters.

Control cyclomatic complexity (e.g., ESLint complexity rule).

Avoid the with statement.

By applying consistent styling, clear naming, purposeful comments, modular file structure, and shallow nesting—supported by tools such as ESLint, Standard Style, husky, and lint‑staged—developers can produce code that is easier to read, understand, and maintain.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptcoding standardsrefactoringnaming conventionscode readabilityESLint
Tencent Cloud Developer
Written by

Tencent Cloud Developer

Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.