{
    "archive_path": "archive/1780759741.602301",
    "base_url": "sumnerevans.com/posts/software-engineering/stop-using-conventional-commits",
    "basename": "",
    "bookmarked_date": "2026-06-06 15:29",
    "canonical": {
        "archive_org_path": "https://web.archive.org/web/sumnerevans.com/posts/software-engineering/stop-using-conventional-commits",
        "dom_path": "output.html",
        "favicon_path": "favicon.ico",
        "git_path": "git/",
        "google_favicon_path": "https://www.google.com/s2/favicons?domain=sumnerevans.com",
        "headers_path": "headers.json",
        "htmltotext_path": "htmltotext.txt",
        "index_path": "index.html",
        "media_path": "media/",
        "mercury_path": "mercury/content.html",
        "pdf_path": "output.pdf",
        "readability_path": "readability/content.html",
        "screenshot_path": "screenshot.png",
        "singlefile_path": "singlefile.html",
        "warc_path": "warc/",
        "wget_path": null
    },
    "domain": "sumnerevans.com",
    "downloaded_at": "2026-06-06T15:29:09.087089+00:00",
    "downloaded_datestr": "2026-06-06 15:29",
    "extension": "",
    "hash": "1DDRT1CCWEYJR6398TAD",
    "history": {
        "archive_org": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--head",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://web.archive.org/save/https://sumnerevans.com/posts/software-engineering/stop-using-conventional-commits/"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-06-06T15:30:22.940718+00:00",
                "index_texts": null,
                "output": "ArchiveError: Failed to find \"content-location\" URL header in Archive.org response.",
                "pwd": "/data/archive/1780759741.602301",
                "schema": "ArchiveResult",
                "start_ts": "2026-06-06T15:30:14.791279+00:00",
                "status": "failed"
            }
        ],
        "dom": [
            {
                "cmd": [
                    "/usr/bin/chromium-browser",
                    "--proxy-server=socks5://tor-socks-proxy:9150",
                    "--disable-features=DarkMode",
                    "--run-all-compositor-stages-before-draw",
                    "--hide-scrollbars",
                    "--autoplay-policy=no-user-gesture-required",
                    "--no-first-run",
                    "--use-fake-ui-for-media-stream",
                    "--use-fake-device-for-media-stream",
                    "--simulate-outdated-no-au='Tue, 31 Dec 2099 23:59:59 GMT'",
                    "--headless=new",
                    "--no-sandbox",
                    "--no-zygote",
                    "--disable-dev-shm-usage",
                    "--disable-software-rasterizer",
                    "--disable-sync",
                    "--window-size=1440,2000",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "--user-data-dir=/data/personas/Default/chrome_profile",
                    "--profile-directory=Default",
                    "--dump-dom",
                    "https://sumnerevans.com/posts/software-engineering/stop-using-conventional-commits/"
                ],
                "cmd_version": "131.0.6778",
                "end_ts": "2026-06-06T15:29:38.332609+00:00",
                "index_texts": null,
                "output": "output.html",
                "pwd": "/data/archive/1780759741.602301",
                "schema": "ArchiveResult",
                "start_ts": "2026-06-06T15:29:21.465274+00:00",
                "status": "succeeded"
            }
        ],
        "favicon": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--max-time",
                    "60",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://www.google.com/s2/favicons?domain=sumnerevans.com"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-06-06T15:29:12.495446+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1780759741.602301",
                "schema": "ArchiveResult",
                "start_ts": "2026-06-06T15:29:09.529308+00:00",
                "status": "succeeded"
            }
        ],
        "git": [],
        "headers": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--head",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://sumnerevans.com/posts/software-engineering/stop-using-conventional-commits/"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-06-06T15:29:12.561625+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1780759741.602301",
                "schema": "ArchiveResult",
                "start_ts": "2026-06-06T15:29:12.531055+00:00",
                "status": "succeeded"
            }
        ],
        "htmltotext": [
            {
                "cmd": [
                    "(internal) archivebox.extractors.htmltotext",
                    "./{singlefile,dom}.html"
                ],
                "cmd_version": "0.8.5rc51",
                "end_ts": "2026-06-06T15:29:55.572775+00:00",
                "index_texts": [
                    "Stop Using Conventional Commits - Sumner Evans  (https://sumnerevans.com/) Sumner Evans  Tech Lead at Can/Am Technologies  (https://sumnerevans.com/) (Sumner Evans)   (https://matrix.to/#/@sumner:nevarro.space) (Matrix)        (mailto:me@sumnerevans.com) (Email)     (https://github.com/sumnerevans) (GitHub)    (https://www.linkedin.com/in/sumnerevans) (LinkedIn)        (https://www.youtube.com/@sumnerevans) (YouTube)     (/index.xml) (RSS Feed)       (https://sumnerevans.com//about) (About)    About  (https://sumnerevans.com//portfolio) (Portfolio)      Portfolio  (https://sumnerevans.com//posts) (Posts)     Posts  ((https://sumnerevans.com//categories) (Categories)       (https://sumnerevans.com//tags) (Tags)      )  (https://sumnerevans.com//categories) (Categories)      Categories  (https://sumnerevans.com//tags) (Tags)     Tags       (Loading...)  Enter a search term above     Stop Using Conventional Commits (https://notbyai.fyi) (Written by Human, Not by AI)   Posted\non 2 June 2026 in (/categories/software-engineering) Software Engineering  \u2022 1882 words\n\u2022 9 minute readTags: (/tags/git) Git , (/tags/commits) Commits , (/tags/scoped-commits) Scoped Commits , (/tags/conventional-commits) Conventional Commits  You\u2019ve almost certainly encountered (https://www.conventionalcommits.org/en/v1.0.0/) ((opens in new tab)) Conventional Commits before.\nIt may have reared its ugly head in the changelog of an open source project\nyou\u2019ve used. It may have been the enforced commit format for an open source\nproject you contributed to. A lot of people swear by it. I swear at it. Even though it is used by (https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md) ((opens in new tab)) a (https://electronjs.org/docs/development/pull-requests#commit-message-guidelines) ((opens in new tab)) large (https://contribute.freecodecamp.org/how-to-contribute-to-the-codebase/) ((opens in new tab)) number (https://jenkins-x.io/community/code/) ((opens in new tab)) of (https://github.com/conventional-changelog/commitlint/blob/master/.github/CONTRIBUTING.md) ((opens in new tab)) popular (https://github.com/semantic-release/semantic-release/blob/master/CONTRIBUTING.md) ((opens in new tab)) open (https://github.com/nuxt/nuxt/blob/main/CONTRIBUTING.md) ((opens in new tab)) source (https://github.com/vitejs/vite/blob/main/.github/commit-convention.md) ((opens in new tab)) projects ,\nConventional Commits is an actively bad standard which encourages focus on the wrong things and fails to deliver on its promises  . Focus Failure       Conventional Commits promises to add semantic meaning to commit messages to aid\ndevelopers and end-users in understanding the changes made in a commit. However,\nConventional Commits fails to do this in spectacular fashion. To demonstrate\nthis, let\u2019s look at the anatomy of a conventional commit. According to the (https://www.conventionalcommits.org/en/v1.0.0/#summary) ((opens in new tab)) Conventional Commit website commit messages should be formatted as follows: <type>[optional scope]: <description>     [optional body]     [optional footer(s)]      The commit\u2019s subject line has a <type> (something like fix , feat , chore , docs , or refactor 1  ) describing the type of change. Following that, there\nis an optional scope, and then a description. This format has a major failing: type is prioritised over scope . This is\nexactly backwards. Scope > Type       The scope of a change (the subject of the change) is the most important part\nof a commit. To demonstrate this, let\u2019s consider why each one of the following\nstakeholders care about the scope of the change more than the type of the\nchange: Contributors: when you are a contributor to a project, you often need to\nread the commit log to identify changes in the codebase relevant to a certain\narea of the code. There are many reasons for this including: Wanting to catch up on what has happened since the last time you\ncontributed. Trying to understand where the project\u2019s overall inertia is. Looking for commits that might conflict with your in-progress work when\npulling or rebasing.  As you read the commit log, you\u2019re looking at what areas were touched. You\nreally do not care about the type of change happening, you care about the scope of the change.  Debuggers: when investigating a bug, you often want to look through the\ncommit log to see what changes might have touched areas related to the\ncomponent where the bug manifested. Once again, the scope is the most\nimportant piece of information. The type of change is entirely useless because\nbugs can be introduced in any change regardless of type. (I\u2019m sure we\u2019ve all\nexperienced writing a bugfix that caused another bug.)  Incident responders: when production is down, scanning the commit log for\nchanges that were made around the time of the outage is an effective way to\nidentify what areas may be causing the problem. Scope is once again the most\nimportant piece of information you can have at this point. For example, if you\nsee a commit related to the auth scope at the tip of the spike of inbound\nAPI errors, it\u2019s a likely culprit for the problem. And once again, type is\nirrelevant because bugs could have been added by any change.   So what does Conventional Commits do? It deprioritises scope so much that it\u2019s optional ! Why the hell is scope optional? Having a commit without a scope is\nlike having a sentence without a subject! Then, to add insult to injury,\nConventional Commits elevates type to the front of the commit message.\nConventional Commits gets the priority of scope and type entirely wrong. Type is Redundant and Restrictive       You might be thinking \u201cso it may be backwards, but commit type is at least still\nimportant, right?\u201d and to that I say \u201cno\u201d. A commit\u2019s description should almost\nalways tell you the type of the change! Consider (https://github.com/angular/angular/commit/ec138c3645f6e28829e69b6da2a839c248bb3bf0) ((opens in new tab)) this commit message as an example: fix(compiler): prevent namespaced SVG <style> elements from being stripped      Even if you only had the description, it\u2019s obvious that it was a bugfix! Space\non the subject line of a commit is already at a premium, wasting characters on\nthe type is not helpful! But it\u2019s often even worse than useless; it\u2019s often\nrestrictive. Take (https://github.com/angular/angular/commit/683172b39a602ac9ec15db69d22853433a67a084) ((opens in new tab)) this commit message as an example: refactor(core): Update webmcp support to use document.modelContext      This commit updated the webmcp functionality in the core component to\nsupport both document.modelContext and navigator.modelContext , so was that a\nbugfix, refactor, or new feature? I would argue it\u2019s all of them! But again, the\nonly thing that really matters is that it was a change to the core/webmcp component. Conventional Commits fundamentally focuses on the wrong thing (the commit\ntype) and devalues the scope (which is what people actually care about).  Broken Promises       So we have determined that the format of Conventional Commits sucks, but it must\nprovide some benefit. Let\u2019s read the (https://www.conventionalcommits.org/en/v1.0.0/#why-use-conventional-commits) ((opens in new tab)) Why Use Conventional Commits  section to see if any of the reasons make any sense. Automatically generating CHANGELOGs.  This is the biggest promise of Conventional Commits: you can run a tool like (https://git-cliff.org/) ((opens in new tab)) git-cliff or (https://github.com/conventional-changelog/conventional-changelog) ((opens in new tab)) conventional-changelog to generate a changelog from the commits since your last release. Is this even\na good idea? No! The audience of a changelog is entirely different than the\naudience for a commit log! A changelog is user-facing, and the user cares about understanding the\nfunctional differences between versions. They care about what changed from a business/functional perspective. A commit log is developer-facing, and the developers care about reading a\nstory of how the codebase has changed over time. They care about what changed\nfrom a scope perspective. As you can see, these are two entirely different grains, and any efforts to\ncombine them result in subpar results. The reasons for this are multiple: In any moderately complex project, it takes multiple commits to land any\nnotable feature. The process of landing the feature (as documented by the\ncommit log) is valuable for developers and contributors, but it\u2019s useless\nfor the end-user. The end-user only cares about the new feature, not how it\nwas built! As (https://richvdh.org/conventional-commits-considered-harmful.html#reverts-are-hard) ((opens in new tab)) Rich pointed out ,\nreverts are problematic for Conventional Commits. Revert commits are\nimportant from a commit log story perspective for developers, but to the end\nuser, a change that is reverted is equivalent to a change not made.   Automatically determining a semantic version bump (based on the types of\ncommits landed).  This sounds nice, but the realities of software engineering often interfere\nsignificantly with the viability of accurately accomplishing this task.\nConsider the following situations: Reverts: imagine a situation where the breaking change you introduced\nwas actually so breaking that you have to revert it? Your tooling will pick\nup a breaking change and increment the major version even though the\nbreakage was actually reverted and there is no breaking change. Accidental breakages: maybe the breakage is subtle and you don\u2019t realise\na change is a breaking change when you make the change. Only in retrospect\nrealise that it\u2019s breaking. You will incorrectly increment a minor/patch\nversion when a major version bump is necessary. Retroactive unbreakages: say you later add a commit which, in\ncomposition with a previously breaking commit, results in a diff which is\nnot breaking. Similar to the revert situation, tooling would incorrectly\nidentify a breaking change.  In such situations, you could rewrite history with a rebase, but that often\nbreaks or is prevented by workflows. It also presents a revisionist history to\nthe contributors trying to contribute to the project, reducing the reliability\nof the story the commit log is telling.  Communicating the nature of changes to teammates, the public, and other\nstakeholders.  As we have established up to this point, teammates and the public have very\ndifferent needs from a changelog and commit log. Conventional Commits manages\nto solve neither.  Triggering build and publish processes.  This is just a bad idea. Say you only run automated security checks on commits\nthat touch code and then someone creates a Trojan-horse commit titled docs: fix typos which actually introduces vulnerabilities into the\nauthentication subsystem? Obviously, that sort of malicious activity would\nhopefully be caught in code review, but the automated tooling is bypassed,\nputting the onus on a human to identify the problem. Compute is cheap, just use git diff to identify changed files (scope, once\nagain) and run build/publish processes based on that.  Making it easier for people to contribute to your projects, by allowing them\nto explore a more structured commit history.  More structured, sure. Making it easier to contribute? Not at all (as we have\nalready demonstrated at length).   Not a single one of the \u201cselling points\u201d for Conventional Commits actually holds\nwater. Conventional Commits is also extremely difficult to apply to a project. You are\nsupposed to define your own set of \u201ctypes\u201d, but pretty much everyone just takes\nthe defaults from (https://github.com/conventional-changelog/commitlint) ((opens in new tab)) commitlint which often\ndon\u2019t fit well with the particulars of individual projects. This problem is\nespecially acute in corporate environments where change management and audit\nrequirements often mandate a ticket number in every commit message. The <scope> field is the obvious place to put it, but this ends up replacing the\nonly useful metadata in a Conventional Commit with a completely useless ticket\nnumber. A Better Way       So what should you do instead? Follow the lead of truly successful software\nprojects like Linux, FreeBSD, Git, Go, and NixOS! What do these projects have in\ncommon? They all use scope-prefixed commit messages (where \u201cscope\u201d is defined to\nbe relevant to the actual project). Usually, the scope to use on a given project\nis self-evident. For the Linux kernel, the subsystem is the natural scope. For\nGo projects, the package path is the natural scope. For a project using a\nmicroservice architecture, the microservice name is the natural scope. Here are some examples of projects and their commit format guidelines. Project Format Example   (https://www.kernel.org/doc/html/v4.14/process/submitting-patches.html) ((opens in new tab)) Linux  subsystem: description  (https://github.com/torvalds/linux/commit/1d774589f924) ((opens in new tab)) i2c: virtio: mark device ready before registering the adapter    (https://freebsdfoundation.org/wp-content/uploads/2020/11/Writing-Commit-Messages.pdf) ((opens in new tab)) FreeBSD  prefix: Description  (https://github.com/freebsd/freebsd-src/commit/f77d37cffdf3) ((opens in new tab)) linuxulator: Return EINVAL for invalid inotify flags    (https://git-scm.com/docs/SubmittingPatches) ((opens in new tab)) Git  area: description  (https://github.com/git/git/commit/62319b49bbe7) ((opens in new tab)) gitlab-ci: update macOS image    (https://go.dev/wiki/CommitMessage) ((opens in new tab)) Go  package: description  (https://github.com/golang/go/commit/517d4d3c7976) ((opens in new tab)) net/http/cookiejar: add godoc links    (https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md) ((opens in new tab)) nixpkgs  pkg-name: description  (https://github.com/NixOS/nixpkgs/commit/7bf858875a54) ((opens in new tab)) xwayland: 24.1.11 -> 24.1.12    (https://github.com/nodejs/node/blob/main/doc/contributing/pull-requests.md#commit-message-guidelines) ((opens in new tab)) Node.js  subsystem: description  (https://github.com/nodejs/node/commit/5f727fdc89c06782652bfbf6a4d05ade1db3d2c8) ((opens in new tab)) stream: fast-path stateless transform flush results      Unfortunately, despite being used by some of the most successful open source\nprojects ever created, this commit style seems to have lost the branding war. I\nintend to change that. Introducing (https://scopedcommits.com) ((opens in new tab)) scopedcommits.com . The website is dedicated to\nadvocating for a return to commit message sanity, and separating the concern of\nchangelog generation from commit log management. Conclusion       Conventional Commits\u2019 purported advantages are actually illusory and the\nindustry has seen no tangible benefit from using it as a standard. However,\nConventional Commits unfortunately seems to have become fairly popular in open\nsource projects, and due to this it seems like AIs have a habit of defaulting to\nusing it for commit messages. This has caused propagation of anti-pattern-ridden\ncommit messages across projects. My goal in this article is to fight against Conventional Commits\u2019 dominance, and\ndemonstrate that there better ways to structure commit messages. But if this\narticle has not convinced you to stop using Conventional Commits, I look forward\nto the flame war in the comment section. Technically, the Conventional Commits specification only defines fix and feat and leaves additional types up to individual projects to specify,\nhowever most projects just end up using the types (https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional#type-enum) ((opens in new tab)) defined by commitlint ,\nso I have included some of them in this list. \u21a9\ufe0e        (https://sumnerevans.com/posts/software-engineering/resume-tips/) (Three Resume Tips) \u00ab Three Resume Tips  RELATED POSTS  (/posts/software-engineering/resume-tips/) Three Resume Tips  in (/categories/software-engineering) Software Engineering on 7 May 2026  (/posts/software-engineering/building-swe-career-in-llm-world/) Building a Software Career in an LLM World  in (/categories/software-engineering) Software Engineering on 2 September 2025  (/posts/software-engineering/vibe-coding-doesnt-require-llms/) Vibe Coding Doesn't Require LLMs  in (/categories/software-engineering) Software Engineering , (/categories/programming) Programming on 10 August 2025  (/posts/software-engineering/7-things-ive-learned-in-7-years-as-swe/) 7 Things I've Learned After 7 Years as a Software Engineer  in (/categories/software-engineering) Software Engineering , (/categories/hackathons) Hackathons on 6 July 2025  (/posts/software-engineering/what-happens-after-you-push/) What Happens After You Push?  in (/categories/software-engineering) Software Engineering on 25 February 2025     ARTICLES FROM BLOGS I FOLLOW Generated by (https://git.sr.ht/~sircmpwn/openring) openring   (https://www.wheresyoured.at/premium-the-haters-guide-to-the-ai-bubble-3-0/) Premium: The Hater's Guide To The AI Bubble 3.0  via (https://www.wheresyoured.at/) Ed Zitron's Where's Your Ed At on 2026-06-05  (https://matrix.org/blog/2026/06/05/this-week-in-matrix-2026-06-05/) This Week in Matrix 2026-06-05  via (https://matrix.org) Matrix.org on 2026-06-05  (https://seangoedecke.com/anti-ai-nostalgia/) Anti-AI nostalgia and the cult of the past  via (https://seangoedecke.com) seangoedecke.com RSS feed on 2026-06-04  (https://lukaswerner.com/post/2026-05-27@genz-neoengineer) GenZ Neoengineers  via (https://lukaswerner.com) Lukas Werner on 2026-05-27  (https://www.micahbird.com/p/book-review-careless-people-by-sarah-wynn-williams-/) Book Review: Careless People by Sarah Wynn-Williams - \u2b50\u2b50\u2b50\u2b50\u2b50  via (https://www.micahbird.com/) Micah Bird's Site on 2026-05-24     COMMENTS Powered by (https://isso-comments.de/) Isso   Please enable JavaScript to view comments.  (Type Comment Here (at least 3 chars))       Name (John Doe) ()  E-mail (optional) (johndoe@example.com) ()  Website (optional) (https://example.com) ()  (Submit)  (Preview)  (Edit)   Subscribe to email notification of replies       Built with (https://gohugo.io/) Hugo using (https://github.com/sumnerevans/sumnerevans.com/tree/master/themes/smol) my fork of the smol theme . Switch to the dark | light | browser theme.  \u00a9 2026 Sumner Evans. All Rights Reserved.    "
                ],
                "output": "htmltotext.txt",
                "pwd": "/data/archive/1780759741.602301",
                "schema": "ArchiveResult",
                "start_ts": "2026-06-06T15:29:55.538912+00:00",
                "status": "succeeded"
            }
        ],
        "media": [
            {
                "cmd": [
                    "/usr/local/bin/yt-dlp",
                    "--restrict-filenames",
                    "--trim-filenames",
                    "128",
                    "--write-description",
                    "--write-info-json",
                    "--write-annotations",
                    "--write-thumbnail",
                    "--no-call-home",
                    "--write-sub",
                    "--write-auto-subs",
                    "--convert-subs=srt",
                    "--yes-playlist",
                    "--continue",
                    "--no-abort-on-error",
                    "--ignore-errors",
                    "--geo-bypass",
                    "--add-metadata",
                    "--format=(bv*+ba/b)[filesize<=750m][filesize_approx<=?750m]/(bv*+ba/b)",
                    "--skip-download",
                    "--cache-dir=/data/yt-dlp-cache/",
                    "--cookies=/data/yt-dlp-cache/cookies.txt",
                    "--proxy=socks5://tor-socks-proxy:9150",
                    "--no-playlist",
                    "https://sumnerevans.com/posts/software-engineering/stop-using-conventional-commits/"
                ],
                "cmd_version": "2024.10.7",
                "end_ts": "2026-06-06T15:30:14.504667+00:00",
                "index_texts": [],
                "output": "media/",
                "pwd": "/data/archive/1780759741.602301",
                "schema": "ArchiveResult",
                "start_ts": "2026-06-06T15:29:57.906165+00:00",
                "status": "succeeded"
            }
        ],
        "mercury": [
            {
                "cmd": [
                    "/home/archivebox/.npm/bin/postlight-parser",
                    "https://sumnerevans.com/posts/software-engineering/stop-using-conventional-commits/"
                ],
                "cmd_version": "2.2.3",
                "end_ts": "2026-06-06T15:29:55.501033+00:00",
                "index_texts": null,
                "output": "mercury/",
                "pwd": "/data/archive/1780759741.602301",
                "schema": "ArchiveResult",
                "start_ts": "2026-06-06T15:29:52.426757+00:00",
                "status": "succeeded"
            }
        ],
        "pdf": [],
        "readability": [
            {
                "cmd": [
                    "/home/archivebox/.npm/bin/readability-extractor",
                    "/tmp/tmpo8on4nzl",
                    "https://sumnerevans.com/posts/software-engineering/stop-using-conventional-commits/"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2026-06-06T15:29:42.450283+00:00",
                "index_texts": [
                    "You\u2019ve almost certainly encountered\nConventional Commits before.\nIt may have reared its ugly head in the changelog of an open source project\nyou\u2019ve used. It may have been the enforced commit format for an open source\nproject you contributed to. A lot of people swear by it. I swear at it.Even though it is used by\na\nlarge\nnumber\nof\npopular\nopen\nsource\nprojects,\nConventional Commits is an actively bad standard which\nencourages focus on the wrong things and\nfails to deliver on its promises.Focus Failure\nConventional Commits promises to add semantic meaning to commit messages to aid\ndevelopers and end-users in understanding the changes made in a commit. However,\nConventional Commits fails to do this in spectacular fashion. To demonstrate\nthis, let\u2019s look at the anatomy of a conventional commit. According to the\nConventional Commit website\ncommit messages should be formatted as follows:<type>[optional scope]: <description>\n\n[optional body]\n\n[optional footer(s)]\nThe commit\u2019s subject line has a <type> (something like fix, feat, chore,\ndocs, or refactor1) describing the type of change. Following that, there\nis an optional scope, and then a description.This format has a major failing: type is prioritised over scope. This is\nexactly backwards.Scope > Type\nThe scope of a change (the subject of the change) is the most important part\nof a commit. To demonstrate this, let\u2019s consider why each one of the following\nstakeholders care about the scope of the change more than the type of the\nchange:Contributors: when you are a contributor to a project, you often need to\nread the commit log to identify changes in the codebase relevant to a certain\narea of the code. There are many reasons for this including:Wanting to catch up on what has happened since the last time you\ncontributed.Trying to understand where the project\u2019s overall inertia is.Looking for commits that might conflict with your in-progress work when\npulling or rebasing.As you read the commit log, you\u2019re looking at what areas were touched. You\nreally do not care about the type of change happening, you care about the\nscope of the change.Debuggers: when investigating a bug, you often want to look through the\ncommit log to see what changes might have touched areas related to the\ncomponent where the bug manifested. Once again, the scope is the most\nimportant piece of information. The type of change is entirely useless because\nbugs can be introduced in any change regardless of type. (I\u2019m sure we\u2019ve all\nexperienced writing a bugfix that caused another bug.)Incident responders: when production is down, scanning the commit log for\nchanges that were made around the time of the outage is an effective way to\nidentify what areas may be causing the problem. Scope is once again the most\nimportant piece of information you can have at this point. For example, if you\nsee a commit related to the auth scope at the tip of the spike of inbound\nAPI errors, it\u2019s a likely culprit for the problem. And once again, type is\nirrelevant because bugs could have been added by any change.So what does Conventional Commits do? It deprioritises scope so much that it\u2019s\noptional! Why the hell is scope optional? Having a commit without a scope is\nlike having a sentence without a subject! Then, to add insult to injury,\nConventional Commits elevates type to the front of the commit message.\nConventional Commits gets the priority of scope and type entirely wrong.Type is Redundant and Restrictive\nYou might be thinking \u201cso it may be backwards, but commit type is at least still\nimportant, right?\u201d and to that I say \u201cno\u201d. A commit\u2019s description should almost\nalways tell you the type of the change! Consider\nthis commit message\nas an example:fix(compiler): prevent namespaced SVG <style> elements from being stripped\nEven if you only had the description, it\u2019s obvious that it was a bugfix! Space\non the subject line of a commit is already at a premium, wasting characters on\nthe type is not helpful! But it\u2019s often even worse than useless; it\u2019s often\nrestrictive. Take\nthis commit message\nas an example:refactor(core): Update webmcp support to use document.modelContext\nThis commit updated the webmcp functionality in the core component to\nsupport both document.modelContext and navigator.modelContext, so was that a\nbugfix, refactor, or new feature? I would argue it\u2019s all of them! But again, the\nonly thing that really matters is that it was a change to the core/webmcp\ncomponent.Conventional Commits fundamentally focuses on the wrong thing (the commit\ntype) and devalues the scope (which is what people actually care about).Broken Promises\nSo we have determined that the format of Conventional Commits sucks, but it must\nprovide some benefit. Let\u2019s read the\nWhy Use Conventional Commits\nsection to see if any of the reasons make any sense.Automatically generating CHANGELOGs.This is the biggest promise of Conventional Commits: you can run a tool like\ngit-cliff or\nconventional-changelog\nto generate a changelog from the commits since your last release. Is this even\na good idea? No! The audience of a changelog is entirely different than the\naudience for a commit log!A changelog is user-facing, and the user cares about understanding the\nfunctional differences between versions. They care about what changed from a\nbusiness/functional perspective.A commit log is developer-facing, and the developers care about reading a\nstory of how the codebase has changed over time. They care about what changed\nfrom a scope perspective.As you can see, these are two entirely different grains, and any efforts to\ncombine them result in subpar results. The reasons for this are multiple:In any moderately complex project, it takes multiple commits to land any\nnotable feature. The process of landing the feature (as documented by the\ncommit log) is valuable for developers and contributors, but it\u2019s useless\nfor the end-user. The end-user only cares about the new feature, not how it\nwas built!As\nRich pointed out,\nreverts are problematic for Conventional Commits. Revert commits are\nimportant from a commit log story perspective for developers, but to the end\nuser, a change that is reverted is equivalent to a change not made.Automatically determining a semantic version bump (based on the types of\ncommits landed).This sounds nice, but the realities of software engineering often interfere\nsignificantly with the viability of accurately accomplishing this task.\nConsider the following situations:Reverts: imagine a situation where the breaking change you introduced\nwas actually so breaking that you have to revert it? Your tooling will pick\nup a breaking change and increment the major version even though the\nbreakage was actually reverted and there is no breaking change.Accidental breakages: maybe the breakage is subtle and you don\u2019t realise\na change is a breaking change when you make the change. Only in retrospect\nrealise that it\u2019s breaking. You will incorrectly increment a minor/patch\nversion when a major version bump is necessary.Retroactive unbreakages: say you later add a commit which, in\ncomposition with a previously breaking commit, results in a diff which is\nnot breaking. Similar to the revert situation, tooling would incorrectly\nidentify a breaking change.In such situations, you could rewrite history with a rebase, but that often\nbreaks or is prevented by workflows. It also presents a revisionist history to\nthe contributors trying to contribute to the project, reducing the reliability\nof the story the commit log is telling.Communicating the nature of changes to teammates, the public, and other\nstakeholders.As we have established up to this point, teammates and the public have very\ndifferent needs from a changelog and commit log. Conventional Commits manages\nto solve neither.Triggering build and publish processes.This is just a bad idea. Say you only run automated security checks on commits\nthat touch code and then someone creates a Trojan-horse commit titled\ndocs: fix typos which actually introduces vulnerabilities into the\nauthentication subsystem? Obviously, that sort of malicious activity would\nhopefully be caught in code review, but the automated tooling is bypassed,\nputting the onus on a human to identify the problem.Compute is cheap, just use git diff to identify changed files (scope, once\nagain) and run build/publish processes based on that.Making it easier for people to contribute to your projects, by allowing them\nto explore a more structured commit history.More structured, sure. Making it easier to contribute? Not at all (as we have\nalready demonstrated at length).Not a single one of the \u201cselling points\u201d for Conventional Commits actually holds\nwater.Conventional Commits is also extremely difficult to apply to a project. You are\nsupposed to define your own set of \u201ctypes\u201d, but pretty much everyone just takes\nthe defaults from\ncommitlint which often\ndon\u2019t fit well with the particulars of individual projects. This problem is\nespecially acute in corporate environments where change management and audit\nrequirements often mandate a ticket number in every commit message. The\n<scope> field is the obvious place to put it, but this ends up replacing the\nonly useful metadata in a Conventional Commit with a completely useless ticket\nnumber.A Better Way\nSo what should you do instead? Follow the lead of truly successful software\nprojects like Linux, FreeBSD, Git, Go, and NixOS! What do these projects have in\ncommon? They all use scope-prefixed commit messages (where \u201cscope\u201d is defined to\nbe relevant to the actual project). Usually, the scope to use on a given project\nis self-evident. For the Linux kernel, the subsystem is the natural scope. For\nGo projects, the package path is the natural scope. For a project using a\nmicroservice architecture, the microservice name is the natural scope.Here are some examples of projects and their commit format guidelines.ProjectFormatExampleLinuxsubsystem: descriptioni2c: virtio: mark device ready before registering the adapterFreeBSDprefix: Descriptionlinuxulator: Return EINVAL for invalid inotify flagsGitarea: descriptiongitlab-ci: update macOS imageGopackage: descriptionnet/http/cookiejar: add godoc linksnixpkgspkg-name: descriptionxwayland: 24.1.11 -> 24.1.12Node.jssubsystem: descriptionstream: fast-path stateless transform flush resultsUnfortunately, despite being used by some of the most successful open source\nprojects ever created, this commit style seems to have lost the branding war. I\nintend to change that. Introducing\nscopedcommits.com. The website is dedicated to\nadvocating for a return to commit message sanity, and separating the concern of\nchangelog generation from commit log management.Conclusion\nConventional Commits\u2019 purported advantages are actually illusory and the\nindustry has seen no tangible benefit from using it as a standard. However,\nConventional Commits unfortunately seems to have become fairly popular in open\nsource projects, and due to this it seems like AIs have a habit of defaulting to\nusing it for commit messages. This has caused propagation of anti-pattern-ridden\ncommit messages across projects.My goal in this article is to fight against Conventional Commits\u2019 dominance, and\ndemonstrate that there better ways to structure commit messages. But if this\narticle has not convinced you to stop using Conventional Commits, I look forward\nto the flame war in the comment section."
                ],
                "output": "readability/",
                "pwd": "/data/archive/1780759741.602301",
                "schema": "ArchiveResult",
                "start_ts": "2026-06-06T15:29:39.213158+00:00",
                "status": "succeeded"
            }
        ],
        "screenshot": [],
        "singlefile": [],
        "title": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://sumnerevans.com/posts/software-engineering/stop-using-conventional-commits/"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-06-06T15:29:38.424340+00:00",
                "index_texts": null,
                "output": "Stop Using Conventional Commits - Sumner Evans",
                "pwd": "/data/archive/1780759741.602301",
                "schema": "ArchiveResult",
                "start_ts": "2026-06-06T15:29:38.402940+00:00",
                "status": "succeeded"
            }
        ],
        "wget": []
    },
    "icons": null,
    "is_archived": true,
    "is_static": false,
    "latest": {
        "archive_org": "ArchiveError: Failed to find \"content-location\" URL header in Archive.org response.",
        "dom": "output.html",
        "favicon": "favicon.ico",
        "git": null,
        "media": "media/",
        "pdf": null,
        "screenshot": null,
        "singlefile": null,
        "title": "Stop Using Conventional Commits - Sumner Evans",
        "warc": null,
        "wget": null
    },
    "link_dir": "/data/archive/1780759741.602301",
    "newest_archive_date": "2026-06-06T15:30:14.791279+00:00",
    "num_failures": 1,
    "num_outputs": 8,
    "oldest_archive_date": "2026-06-06T15:29:09.529308+00:00",
    "path": "/posts/software-engineering/stop-using-conventional-commits/",
    "schema": "Link",
    "scheme": "https",
    "snapshot_abid": "snp_01KTERTH9KE40C4EE301GSGV3W",
    "snapshot_id": "848a649f-ac8c-459f-8af5-e0b161986c7c",
    "sources": [
        "/data/sources/1780759739-import.txt"
    ],
    "tags": null,
    "tags_str": "",
    "timestamp": "1780759741.602301",
    "title": "Stop Using Conventional Commits - Sumner Evans",
    "url": "https://sumnerevans.com/posts/software-engineering/stop-using-conventional-commits/"
}