Being a tech lead for Hack4Impact has been a great experience - one that I would recommend to everyone. It teaches you how to work in software development beyond just technical skills.
Engaging with the Team
The success on your project relies on your team members being a team - the whole being more than the sum of the pieces. To do this, take great steps in learning about each members and what role they play in the project.
Before even starting development, meet with each of your members and understand their strengths and weaknesses. As a lead, this should go beyond just technical skill - strive to understand their holistic skillset and imagine how they fit into the team.
In addition, ask them what areas of technology they want to learn and are interested in. Understanding these are important, because often people are most motivated when working on something they are interested in learning.
Use mentorship for someone to be able to learn what someone else is good at. And assign people to a balance of what they want to do and what they are good at. Yes, it’s important for people to learn, but it’s also important for the project to get done.
Meeting with people personally on a regular basis is key to always understanding the status of the team at any point. This is important to gauge engagement levels of each member, and also keep track of interests. This will help you assign work accordingly and ensure that all members are working on features that will make them most productive.
To do this, schedule 1 on 1’s with each member regularly and check in when working together every single time. This also gives an opportunity for members to spark dialogue with you and makes it easier for them to bring up any concerns or questions with little hesitation.
Most importantly, always be available to all members. This makes it easy for them to reach out to you and ensures that they trust you and you will be a reliable source of help for them.
Leads often overlook the mindset of their members. It’s important to remember that happy and motivated members is the catalyst for progress, if not a necessity. Generally, it’s okay to be behind on the development schedule as long as your team is motivated and still working hard, are happy, and are close with one another. A great way to do this is to praise often and praise loud.
Never blatantly put down a member, they’ll become even more distant and less motivated to produce good work. That’s not to say that constructive criticism can’t be given - instead, phrase it in a way that will benefit them, such as ways to help their future growth.
The most important thing to remember here is that all members are required to finish work, but not required to finish work well. Make sure your members always opt for the latter on their own initiative.
The worst feeling as a developer is working on a codebase which is messy, poorly maintained, and disorganized; no one will have any idea of what’s happening and its just gross. So, make your repository one which is easy to navigate through and understand for any passerby. This entails a couple of things.
Code reviews are a core process for any software engineer. But first, step back and understand the goal of code reviews. What are they for? They are to ensure that all teammates are productive and maintain the quality standards of the project while contributing to the progress of the project.
Good code reviews not only. help others about learning about the codebase, but also accustom them to push good, reviewable code as well.
- Understand the big picture. Know what code is being requested to be merged and how it fits into the project as a whole. Does it make sense to have this feature? Is this feature implemented well enough that it can be put into production immediately? Also consider the logic that is being pushed - if it is optimized well enough that it would not have to be revisited for a long time.
- Have a conversation. Sometimes, it’s good to reconsider the big idea of the feature. If this is the case, stop typing your thoughts and have a conversation. Having in-person dialogue is important to fully understand the context, and also provides an opportunity to bounce ideas off of one another to improve the feature and its placement in the project.
- Review quickly. The worst thing for a developer is to push code, and have it sit in code review for so long that they lose a good sense of what was written. Make sure that you give feedback quickly and concisely, so that iterations can be done quickly and effectively.
- Stop requesting changes over a nit. For heaven’s sake, just approve the PR, but comment your thoughts. Don’t slow down development progress over a stylistic change, or a small logic rearrangement. Comment your thoughts but approve the PR if everything else looks good. Trust your members to push code that best represents themselves, and prevent trivial barriers that hinder project progress.
Good code quality is something I strive for in all of my projects, regardless of whether they are open-sourced or not. Maintaining a high level of expectation expands the project’s longevity and its prospective for future development, and thus its potential for impact.
Take the time to set up the repository well and create guidelines for contribution. Enforce good practice so that everyone follows suit from the beginning - it’s so much easier to start on the right foot than trying to clean up code halfway through the project. Also note that code quality extends beyond the quality of the actual code - it also includes the quality of the commits and pull request descriptions that are bundled with the development.
- Writing Code
- Code Style: Good code style should always be enforced. Be sure to add a linter or code formatter which is tested and run for every pull request. A good feature to have that ensures that this process is easier is by implementing a pre-commit hook, which will run a basic linter before committing.
- Pull Request Features: Each pull request should have a single clear purpose of feature, or a collection of small fixes that are not enough to comprise a pull request on its own. This helps compartmentalize each feature, and make sure that all commits in the repository are a single feature and not mixed in with one another. Specifically, this helps when viewing diffs, so the viewer knows that the code they are looking at corresponds to exactly one feature. Then, they don’t need to go through it to determine what implements each feature.
- Project Structure: Continuously reflect on the project structure. This includes logic and component compartmentalization in different files, and intuitive directory structure. Do the folders make sense? How many directories deep does one have to go to go to the deepest file? These are all questions to keep in mind.
- Pushing Code
- Pull Request Descriptions: All pull requests should be opened with a substantial summary of what features were implemented and a way to test them. When looking through old code, the PR page is generally the first place that the user will land on to refer back to old code, so its important that its written out well so it makes it easier to find what they are looking for.
- Squash and Merge: Keeping the commit history clean and concise makes it easy to triage bugs and understand which feature was developed at what time. A good way to do this is to always squash all pull requests into a single commit that goes into master.
- Standardized Commit Messages: A simple way to keep the repository seem like its organized and cohesive is to standardize git commits. This could entail adding an emoji to the beginning of the message, enforcing capitalization of the first letter, or anything else. It’s an easy fix that will improve the holistic view of the project repository.
Good documentation is crucial. Ideally, a developer would be able to contribute to the project long after active development has ended. For this to happen, documentation must go hand in hand with development. Some of the previous points address this, such as clean commit messages and good pull request descriptions. However, even more important is to be able to document some of the aspects of the project that these can’t capture.
This might include how to run the project, the reasoning behind the logic and project structure, and any code that is difficult to understand at an initial glance.