Basic aspects for every development team - some thoughts
Developers should be able to focus on writing excellent code to fulfill customers' expectations. By best practices, a further step in this direction is taken. Here are some thoughts.

Type safety
I work with JavaScript. I would recommend using TypeScript, which adds static typing to your project. When refactoring your code, you will have error checks during compile time and a much easier life. It also allows you to change the import behavior from relative to absolute paths. The primary benefit is refactoring. Moving files with absolute imports is less error-prone. There are many more benefits, but I will stop here. If you want to deep-dive into the topic, here is more to read.
Code formatting
A linter analyzes your code for stylistic and programming errors against a set of rules. Applying this makes your code more readable and understandable for the whole team. Additionally, it will save you a lot of time in code reviews. Next to a linter, Prettier helps you make more maintainable code by formatting your code standardized and doing so automatically if applied to the hooks. Never waste time on formatting code or arguing about the rules to apply. Just choose a preset and move on.
Testing
You should (almost) never skip tests. There are a lot of good testing libraries out there, and Vi Test is an excellent option. For further details, see my related article, which compares Jest and Vi Test. It includes a step-by-step setup guide.
Hooks
Husky is a tool that allows us to run some scripts before committing or pushing our code. This is useful for our linter and formatter. The rules get applied automatically. You can use git hooks directly without that dependency. Whatever way you choose, apply your rules automatically. For more details, see here.
Feature Branch Development (Git Flow)
The core idea of this flow is to develop all features in a dedicated branch. This setup consists of two branches: main
and develop.
The main
branch contains the code running on production, and the develop
branch serves as an integration branch for new features.
Instead of working on those two branches, new features are developed on feature branches. Feature branches are created based on the develop
branch. Those feature branches should be named in a certain way, using patterns like feature/<task-number>-short-description.
This way, they can be identified easily.
When a feature is finished, it gets merged into the develop
branch via a Pull Request. While developing on a feature branch, it is essential to rebase the feature branch regularly with the develop
branch to lower the chance of merge conflicts.
Read more about the Git Flow workflow and the feature branch workflow
Writing understandable commit messages
Well-written commit messages should follow a standardized format within the team. This will enable viewers of the codebase to understand the type of change you are making easily. Everybody can understand what happened without reading the code changes in a commit. The commit consists of 4 parts:
- The type of commit
- The scope of the commit (optional, but often nice to have)
- The actual content of the commit
- An optional body for more description. Suitable for larger commits.
The type
You can use your types, but here are the defaults regarding semantic versioning:
- feat: a new feature or change to an existing feature.
- fix: Fixing a bug or known issue in code.
- test: Adding additional tests for existing features.
- chore: Updating build tools, dev dependency updates, etc.
- docs: Update to documentation like
README
Source for further reading: The Conventional Commits
The scope
This is a team-internal context of features. Depending on the project, it makes sense to use Epic names or pages within a Single-Page Application.
The content
Here, you name the ticket number and a (very) short description of the context.
The body
Here, you should describe the reasoning behind your change, enabling other developers to understand it and its impact.
An example
A commit message may look like this:
feat: #issue-1234 submit button
- feat: add new submit button to sign up form
- test: check if the form can be submitted
Rebasing instead of merging
This git feature is handy in a feature branch development workflow. You can integrate changes from one branch into another. With a merge, you'll create a new forward-moving change record. With rebase, you'll rewrite history and move your moment of branching to the point in time as if the rebased branch had already been there before you started developing your feature. The primary reason behind this is to maintain a linear project history. Find a more detailed guide about git rebase and a discussion about rebase vs merge.
Tagging
A tag is a reference to a specific point in git history. You can name a tag. It is most likely used as a marker for a released version (see semantic versioning). A tag cannot change - it has no history of commits. There are two kinds of tags: lightweight and annotated tags.
Lightweight tags are like bookmarks. Similar to a commit message, annotated tags have a tagger name, email, date, and tagging message, which can contain the changelog for a specific version. Find out more here.
Use Semantic Versioning
Semantic versioning, also called "SemVer," is a standard defining the structure of the version number. It consists of three parts: Major.Minor.Patch.
- Major is incremented on breaking changes.
- Minor is incremented when functionality is added in a backward-compatible way.
- Patch is incremented on backward-compatible fixes.
Semantic versioning helps us to use third-party code reliably. If we add an external library, we define the version we want to use. We have several options how to address the range of versions we allow on dependency updates:
- Without any prefix, we define the exact version.
- Caret
^
allows minor and patch updates. - Tilde
~
allows only patch updates.
Final thoughts
I tackled some generic aspects to consider in programming. My key point is to automate stuff and bother only with relevant aspects. Developers and their tools should focus first on the developer experience (DX) and second on productivity. If some change, tool, or agreement increases the joy of work, I would rank it more important than productivity.