This concept is one that one of our brilliant engineers introduced to our team to help us think about how we can improve our processes. It stands for Simple Tech Enhancement Proposals.

The idea is simple 😄 Draft a proposal, share it with the team, debate it and then approve or reject it. Once you have an approved proposal, the team treats it as a first-class citizen and adheres to it going forward.

In order for it to truly work, you need to get buy-in from the team. Everyone needs to be on board and everyone needs to be willing to adhere to the proposals that are approved.

Why do we want it?

  • We are a small team of engineers and we are constantly trying to improve our processes.
  • We are also trying to build a culture of ownership and accountability.
  • We want to empower our engineers to make decisions and take ownership of their work.
  • We want to make sure that we are all on the same page and we are all working towards the same goal.
  • We want our engineers to feel included and heard.

How does it work?

  • We have a dedicated Slack channel for STEP proposals.
  • We use Fibery to manage and comment on the proposals.

Drafting a proposal

When you have an idea for a proposal, you draft it in Fibery. Give an introduction to the problem you are trying to solve. Then, propose a solution and explain why you think it is a good one. Finally, explain how you plan to implement it. Provide working examples and comparisons to existing solutions.

Sharing the proposal

Once you have a draft, you share it with the team in the Slack channel. You can also share it with other teams if you think it is relevant to them.

Debating the proposal

The team will read the proposal and provide feedback. They will ask questions and suggest improvements or alterations. They will also vote on the proposal.

Approving the proposal

Once the team has reached a consensus, the proposal is approved. The proposal is now a first-class citizen and the team will adhere to it going forward.

Rejecting the proposal

If the team cannot reach a consensus, the proposal is rejected and put aside.


Example 1: Magic values should be named


We lack context and can misinterpret strings and numbers in the codebase are mingled with lines of code. These are magic values and are an anti-pattern.


;; Sleep a thread for 5.5 hours (Thread/sleep 19800000)


We will define named constants for all magic values in our code.


We will use the following code to define named constants:

;; Sleep a thread for 5.5 hours (Thread/sleep (* 5.5 60 60 1000)) (let [millis 1000 seconds (* 60 millis) minutes (* 60 seconds) hours (* 60 minutes)] ;; Sleep a thread for 5.5 hours (Thread/sleep (* 5.5 hours)))


This is a simple solution that is easy to implement, understand and implement.


  • Yes
  • No

Example 2: We should use a standardised code formatter


We have a lot of code that is not formatted consistently. This makes it difficult to read and understand the code. When someone changes a file and reformats it, the entire file changes with their current formatting settings. This makes reading diffs very difficult.


We will use a standardised code formatter to format all of our code.


We will use prettier to format our JavaScript code. We will decide on a standardised set of rules and we will configure it based on a team consensus.


This concept in theory is simple, but it can be difficult to implement if you don't get buy in. It is also important to make sure that you don't over-engineer your proposals. Keep them simple and easy to understand.