I have a project in which I'm the sole contributor, there isn't a stable API yet and I'm constantly refactoring code, but I still try to denote breaking changes whenever they do happen. Recently however, the repository for this project has attracted some interest and I decided to establish some conventions to make it easier to write changelogs and attract new contributors, so I adopted the Semantic Commits convention, which is similar to the one used by the Angular project.

Both Angular and Semantic Commits specify certain prefixes for commit messages: "feat" for new features, "fix" for changes which fix a bug, "refactor" for code changes which neither add a feature nor fix a bug, etc.

My question is, going forward, should backwards incompatible changes, like changing the name of a public method, be labelled as "refactoring", if it doesn't actually add a feature in the process?

For example, my project exposes a CLI interface, which expects arguments to set values. If I change the parameter name used to set those values, without changing anything else about their implementation, is it better to label that commit as "refactor" or "feat"?

My reasoning is that "refactor" is appropriate, because I'm not adding anything, I'm just renaming an existing method, but I ask because the way "refactor" is described implies it should be used for changes which don't affect the API, but "feature" also doesn't feel appropriate to convey the change. Is there a preferred practice in this scenario?

1 Answer 1


Refactoring is usually described as altering the internal structure without changing external behavior. Although the name of a public method or the name of a named parameter may not be behavior, it's also not internal structure. I wouldn't typically refer to changing the public interface as a refactoring, especially once you have a stable API. Until you have a stable API, I may be a little more forgiving, since no one should be relying on the behavior of an unstable API.

When you get into versioning and semantic commit messages, you tend to use the commit types since the last release to make informed decisions about whether to increment the major, minor, or patch version number. Any solution should keep this in mind.

Conventional Commits offers a solution. You can append ! to the type to indicate a breaking change. That is, you can continue to use the refactor type to identify development changes that do not explicitly add a feature or fix a bug, but use refactor! to indicate that those development changes will break clients of the API.

If you were to follow the standards of Semantic Versioning, your library or API would have a version of the format 0.x.y up until the API is stable or it is used in production. Using the language of the Angular-style semantic commits, I would consider that feat or any commit with a ! to increment the minor version while the others increment the patch version. After a stable API, any commit type with a ! would be a major version increment, while feat would increment the minor version and the others would tend to increment the patch version or perhaps not trigger a new version at all.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.