JJ's Software Rules
⚠️ Updated (again) based on general life lessons & observations. 11/13/2019, JG
In 17 years of writing code and leading teams, I’ve slowly built a list of software development rules. These rules allow high-quality code to be written quickly. I ask every engineering organization I lead to follow these rules.
Coding
- Write simple code that a freshman computer science student can understand. In general: the simpler, the better. A peer should be able to understand your function in 15 seconds.
- Name symbols – variables, functions, classes, filenames, etc. – precisely and exactly.
- Add a 30,000ft comment at the top of every file, explaining what the file is and why it matters.
- Use clear, plain English when writing comments.
- Explain the purpose of every function with a comment before its signature.
- Comment every step in non-trivial functions. (
Step 1
,Step 2
, etc.) - Follow the linting rules. If you don’t like the rules, open a PR with proposed rule changes and get a supermajority of the team to agree.
- Use custom exceptions amply, so callers can catch errors confidently and application logs are traceable.
- Make no assumptions in your code. Don’t assume a public function’s arguments are safe; don’t assume API’s will be online; don’t assume rows will exist in the database; etc.
- Keep
master
release-ready.Master
branch can never: a) add bugs or regressions, or b) temporarily remove existing features. Assume that production deployment may happen at any time, andmaster
will go to production as-is. - Zero-downtime is required. Wherever humanly possible: don’t write backwards-incompatible API changes; don’t write locking DDL migrations; don’t expect atomic deploys; don’t plan downtime.
- Fully remove unused code. If you remove code/features, all dependencies must be deleted. Never delete the view but leave the controller; never delete the controller but leave the route; never delete the model but leave the table; never delete the function but leave the pip package.
- Strongly prefer a global styleguide. Avoid per-component styling. Work with the design team to define styles in a top, global level styleguide, and then let those styles cascade to each component unabashed.
- Don’t use
TODO
’s. If possible: fix the code now. If that’s not possible: create a ticket for the remaining work that needs to be done, and include a link to that ticket in a code comment. - Strongly prefer the tech we already use. Don’t use another language/framework/tool unless it’s absolutely necessary.
PR’s
- A clear PR title that summarizes the PR is required.
- In every PR description include 2 things: (a) why this PR was necessary, and (b) what you changed.
- Write small, <100 line PR’s that can be deployed to production in baby steps. To avoid being blocked while waiting for PR review, daisy chain subsequent branches/PR’s so they can be reviewed/approved/merged in order.
- Make Single-Type PR’s. A PR is 1 of 4 types: a) refactor & reorganization, where no functionality is changed, b) adding a feature, c) editing a feature, d) deleting a feature. Every PR should be one of these 4 types, and your PR should declare which type it is.
Ops
- Devops code is still code. All the same rules herein apply.
- Avoid manually-executed code. SQL snippets, scripts, and one-time commands should be run programmatically (via migrations, background jobs, deployment pipelines, etc). When automation isn’t possible, create a checklist for every environment where the code needs to be deployed (each developer’s localhost and each hosted environment) and ensure the checklist is completed.
- Make DDL Edits via Migrations. Never make DDL changes in hosted environments manually.
- Check off checklists 100%. Rely on checklists to avoid oversights. Always complete every item on the checklist before advancing to the next project.
Lifestyle
- Over-communicate. There is no punishment for asking too many questions or providing too many status updates.
- Break down the project. Before any code is written, divide the project into a series of baby steps, document the steps on a ticket, and have someone review/edit the steps before starting.
- Finish existing work, like tickets, QA, PR’s, emails, and code reviews, before starting new work.
- If you run out of work to do, proactively seek out what needs to be done next.
- Avoid religious crusades: tabs vs. spaces, emacs vs. vim, etc.
- Raise security concerns as soon as you notice them – either in production or during development.
- Treat PII and confidential information very carefully, as if it was your own.
Individual Performance
- You’re online and working, during the hours we’ve agreed.
- You’re available & reply promptly to chat & email, during the hours we’ve agreed.
- You push a branch/PR with some code every day.
- If you aren’t fluent in English, you continually improve your written and verbal English skills.