Improve Frontend Code Quality with Tools — Version Automation

· 5 min read · 875 Words · -Views -Comments

I’ve been building an internal UI component library to standardize product UI and improve delivery speed instead of reinventing components each time. Great goal, but it exposed a few release headaches.

Libraries evolve and need regular publishing. Our current flow is: change code, commit, bump the version manually, then run the publish command. That causes several issues.

Pain Points

  1. A change might be a fix, a feat, or even a breaking change. Raw commit messages rarely capture that nuance, and we produce no public release notes. Consumers just see a new version number and feel anxious about upgrading.
  2. Manual version bumps are error-prone and inconsistent. A newcomer might mark a tiny CSS fix as a major release. Manual editing is also tedious.
  3. This isn’t limited to UI libraries — app repositories also deserve clear commits. Our internal history has plenty of throwaway messages with little value.
  4. Without standardized commits, every push can trigger CI and even a release pipeline. Documentation-only changes shouldn’t do that. The fix is to enforce structured, conventional commit messages.

Time to lean on tooling. Fortunately, the ecosystem is mature.

Angular as a Reference

Angular’s commit history and changelog are exemplary. How do they do it? https://github.com/angular/angular/commits/master

Semantic Versioning Refresher

Before wiring up the tools, revisit SemVer so version bumps stay meaningful.

MAJOR.MINOR.PATCH with the rules:

  • MAJOR: incompatible API changes.
  • MINOR: backwards-compatible feature additions.
  • PATCH: backwards-compatible bug fixes.

Pre-release identifiers and build metadata can be appended. Full spec: semver.org

Setup

Install the Tooling

yarn add -D commitizen            # commit helper
yarn add -D commitlint            # lint commit messages
yarn add -D cz-conventional-changelog  # Angular-style prompts
yarn add -D standard-version      # SemVer + changelog automation
yarn add -D @commitlint/config-conventional

IDE Plugin

Git Commit Template

  • We use JetBrains IDEs; find equivalents for other editors.
  • The GUI makes structured commits friendlier than the terminal prompt.

package.json

"scripts": {
  "commitmsg": "commitlint -e $GIT_PARAMS",
  "release": "standard-version"
},
"config": {
  "commitizen": {
    "path": "./node_modules/cz-conventional-changelog"
  }
}

commitlint.config.js

module.exports = {
  extends: ["@commitlint/config-conventional"],
  rules: {
    "subject-case": [2, "never", ["upper-case"]]
  }
};

.huskyrc.json

{
  "hooks": {
    "commit-msg": "commitlint -e $GIT_PARAMS"
  }
}

.versionrc.json

Example config: alanhe421/jhipster-starter

Common Commit Types

type describes the scope of change. Frequently used values:

  • feat: new feature (maps to MINOR in SemVer)
  • fix: bug fix (maps to PATCH)
  • to: tweak that moves toward a fix but isn’t final; useful for multi-commit fixes before the concluding fix
  • docs: documentation changes
  • style: formatting, missing semicolons; no production code changes
  • refactor: code restructure without new features or fixes
  • perf: performance improvements
  • test: add/refactor tests; no production code changes
  • chore: tooling, build scripts, maintenance; no production code changes
  • revert: rollback a commit
  • build: build system changes
  • ci: CI-related changes such as hooks or Docker configs

Full spec: Conventional Changelog Config

The to type comes from an Alibaba practice described here. It lets multiple incremental commits link to one eventual fix; the changelog groups them so you don’t get duplicates when to entries are marked as hidden: false.

Workflow

Making a Commit

  1. Use the IDE commit panel and enable the commit template. Fill out each field according to the prompts.

  2. When it’s time to publish, run npm run release. The script updates CHANGELOG.md, bumps the version, and creates a commit automatically.

    • First run: npm run release -- --first-release
    • Prefer triggering releases in CI.

Notes

  1. Commits that don’t match the format fail immediately thanks to Git hooks.

  2. Because enforcement happens via local hooks, someone could disable .huskyrc.json and bypass checks. If that becomes a problem, add server-side hooks.

Pre-release Versions

Sometimes you need a fresh version for testing without blocking ongoing development. Use the pre-release flag:

# "alpha" can also be "beta" or "rc"
npm run release -- --prerelease alpha

Alpha, Beta, RC Refresher

  • alpha: internal test builds with rough edges and incomplete features; meant for developers/testers.
  • beta: public test builds; more stable than alpha but still experimental.
  • rc: release candidate; feature complete and essentially what will ship.
  • stable: the final GA release.

Ordering example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.

Keep the process pragmatic for small projects.

Troubleshooting

  1. Duplicate changelog entries

    I once saw repeated sections across releases. It was an upstream bug; reinstalling/upgrading the package fixed it. Keep your release tooling current.

    Upstream issue

    standard-version derives the next release from two data points: the version in package.json and the commits since the latest tag (git describe --tags --abbrev=0).

    For example, if you delete local tags v0.1.14 and v0.1.13 and run npm run release, the new version includes commits from both tags, so the changelog shows both feat and build entries.

  2. Bypassing hooks

    Git hooks rely on shell scripts. If developers deliberately disable them, commits still pass locally. Server-side hooks are the only airtight safeguard.

Final Thoughts

  • Well-structured commit messages matter; compare Angular’s history with a typical repo and the gap is stark.
  • Quality history helps new contributors ramp up and makes defect tracking easier.
  • Enforcing conventions has a cost, but the benefits outweigh it.
  • Good habits pay dividends for years—embrace them.

References

Authors
Developer, digital product enthusiast, tinkerer, sharer, open source lover