New Feature Checklist

The following list could be used for reviewing PRs, as well as for reviewing your own code before you push it.

Writing these down led to the revelations that 1) most of these are related to state in the app, and 2) nearly all UX-related. (That’s right, being thoughtful about UX is not just for designers but also for engineers.)

This doesn’t cover everything that a quality PR review should handle. This is assuming you have already reviewed the logic of the code itself for errors, best practices, potential conflicts, etc. This also assumes that the feature meets the ticket’s spec, and is something that your application truly needs

These questions are more about whether this new feature works.

The Checklist

Accessibility
It’s just simple courtesy to make sure you have covered basic accessibility around your new feature. 

Have you ensured your text size is scalable and isn’t cut off when the user has toggled on a larger text size? Are you supporting both light and dark mode? Does content have captions or descriptions provided for users that require a screen reader?

Empty state
What happens when there is no data to populate this feature’s views? If a view is loading or taking a long time to load, is the user shown a loading spinner or dummy UI to indicate as such?

First use
Does this feature work correctly the first time is it used? Should there be some instruction for the user the first time this is accessed? Does the feature correctly distinguish between the first use and other potential empty states?

Offline mode
Will the feature work if the user is offline? Are there any views that require an internet connection to load? Is there data that could be cached to make the feature work without too much friction when the internet is not available?

There may also be situations where even just bad network conditions or slow wifi can cause glitches with UI, persistence, etc. Testing with the Network Link Conditioner can also help to reveal race conditions.

Localization
If possible, does this feature support localizing text direction, language, currency, time, units of measurement, etc? 

Authentication
Is the user’s login state detected and handled appropriately? How is unauthorized access dealt with? Does this feature work correctly for any arbitrary user account type? Is this hidden from users who should not see it?

Some apps may have more and less complicated authentication flows with multiple auth states: logged in, not logged in, logged in with a valid oauth token, attempted login with an expired token, etc. Others may not have user accounts at all. Are all of the reasonable login states addressed?

Accessing from unusual routes
Will this feature still work if accessed via deep linking, universal linking, etc? Is it accessible or able to be launched from everywhere in the app that it should be?

Persistence
Are things that should be saved from one session to the next persisted in the correct place (server vs. client, UserDefaults vs. File Storage, etc)? Are they saved at the right time in the flow of interaction? 

Should the app remember the user’s last state when they interact with this feature? For example, consider how Chrome remembers the last tab you were on when you open the app again or how your email client saves your draft.

Multiple users
Does your logic account for scenarios involving multiple users? Is there a possibility for race conditions?

CRUD
If this feature contains interactive components, do these support all four elements of CRUD?

Navigation
Is it easy to navigate backwards? Does moving backward or forward from this feature take the user where they would expect to go?

Programming Streak Recap: 550 Days of Code

While working through the 100 Days of Swift challenge last year I started a programming streak to help motivate myself to be more consistent. The deal was that I could count a day towards my streak if I spent a minimum of 20 minutes programming, with the original goal of getting at least 30 days in a row. I also happen to track my time generally (using the 15 minute increments, as in the method described in Laura Vanderkam’s Off The Clock), so I know almost exactly how much time I’ve spent programming over the last few years, including before the streak started.

The streak recently passed 550 days— about a year and a half— and I thought I’d run some numbers to see how it’s been working out. First, let’s look at some summary stats as of that 550 day mark:

  • Total streak hours: 1080.75

  • Total streak hours in 2021: 722

  • Streak theoretical minimum total hours: 183.33

  • Total pre-code streak hours: 59.75

  • Streak average hours per day total: 1.97

  • Streak average hours per day 2020: 1.14

  • Streak average hours per day 2021: 2.25

  • Streak average hours per working day: 3.13

  • Pre-code- streak average per day: 0.44

One thing that caught my eye immediately was that even though all that’s required to keep the streak going is 20 min/day, the actual average output is nearly seven times the minimum (2.25 hours or 135 min/ day). This shows that the return value on maintaining a streak is that it acts as a multiplier by creating momentum at the level of individual sessions and between sessions as well. The low minimum time requirement is helpful because it makes it easier to keep the streak going without burning out.

Additionally, the average time spent programming daily increased greatly from before the streak started (0.44 hrs/ day) to during the streak (1.97 hrs/day average overall). It also increased year over year as well, with an average of 1.14hrs/day in 2020 shooting up to an average of 2.25hrs/ day in 2021. This jumps up further to 2.69hrs/ day by September of this year.

There is also immense value in not having to restart projects over and over after time off. It’s easier to be productive when you touch a project frequently—even for a short period of time— because starting is harder than continuing. Additionally, it’s pretty easy to extend that daily time far beyond the minimum because once you get engrossed in a project you’ll likely just keep going anyway. That sense of flow and getting lost in the work is what makes programming so enjoyable in the first place, and produces better outcomes overall.

Alright, let’s talk about the elephant in the room: the average full-time employee puts in 8 hours per workday, so how can 2.25 hours be considered a good effort? Well, it’s not that simple. Study after study has shown that the most workers (including programmers) aren’t productive for a full 8 hours. While the average employee is clocked-in for 8.8 hours a day, they tend to be productive on their primary responsibilities for only 2.88 hours a day, with the rest of their time spent on personal activities like reading the news, checking social media, and answering emails.

I put in time towards my streak every day—because that’s how streaks work!— but if I wanted to compare my productivity to that of a full-time developer, I could instead average my total 2021 hours over only the working days that occurred in this period (this subtracts government holidays and weekends). Then the streak’s average becomes 3.13 hours per day, which is a quarter of an hour more daily productivity than the average worker. And because a streak is a multiplier day over day, this tiny bump adds up to 57.75 more hours of coding in 2021 than the studies linked above would predict.

Because of how my time tracking system works, pretty much all of the time that gets counted toward the streak is “head down” work that is on task. I’m by no means 100% efficient with my time generally (no one is!) but the time that gets counted toward the programming streak represents the reality well because when I’m doing anything else for more than a few minutes things it gets attributed to other activities in my timesheet (hence why I’m not logging 8 hours a day of programming even if I’m at my laptop for 8 hours or more). There is a margin of error for rounding, but I’ll save the discussion of my time tracking and statistical methodology for another time.

As these numbers demonstrate, I’m getting a lot of personal value (not to mention eudaimonic joy) out of this streak, so I plan to keep it going for a while more. But I understand that this wouldn’t work for everyone and that some people would be left feeling burned out by the “do at least a little of x thing everyday” approach and that’s okay. I know many programmers sing the praises of staying up all night on a 13hr programming binge (though no one ever mentions how the day after that goes), and I’m offering a less glamorous counterpoint. It’s a bit of a tortoise v. hare situation. I only have data to support my slow-and-steady approach, so if any hares want to chime in with their data I’m all ears!