Dan's Musings

Why 80 Characters Wide Still Matters

I am a firm believer that code should be written at a width of 80 characters.

Code written at 80 characters wide? What is this? Even Linus doesn't agree at this point.

Why does 80 characters still matter to me?

I initially started using it because when I wanted to get into VMware machines from inside vSphere, say because the network went down or the SSH key was missing, I could still read my code and debug it if needed. The console screen was -- you guessed it -- 80 characters wide.

Even now it still matters. My code can be read by someone else. Maybe it will be read by someone who doesn't use the terminal much, and just leaves it at the default screen width of 80 characters. Maybe my code will be viewed by someone over Google Meet, or from a video years after the video was made. I want my code to be readable by others, no matter from what setting they are reading the code.

column-check

I made a repo on github and sr.ht [edit: I have since deleted my sr.ht account] to check what different screen arangements would work with different column widths.

The README has 3 listings, herein called "rulers", which have numbers listed that are designed to easily show how wide their lines are.

Another file, rulers.txt, simply has the contents of the listings in a text file so the rulers can be viewed "raw", without being rendered as a README listing.

I used this repository to try many different screen configurations to see which column width displayed in the most configurations without being cut off.

Admittedly, most screen configurations I tested worked with all column widths. Surprisingly, some of the configurations I tested cut off all column widths, even at 80 characters. This was mostly when I tried viewing the repository on a phone screen (though viewing rulers.txt on landscape mode on my Motorola did faithfully render the 80 and even 100 characters ruler without going off the page). This post will ignore phone screens, however, because they are not generally used for developing software.

The point still stands that 80 characters works almost everywhere, even on default settings, when other widths would not work.

What follows are some examples of the 80 character width winning in the wild.

Admittedly Hand-Picked Examples

This is a screenshot of PR #1.

GitHub PR Page

It was viewed on a 1080p screen that has been rotated to be long.

I have 1080p screens flipped in portrait mode, and I use them together with my actual laptop screen when working from home or work.

If you look at the image above, you'll see that the PR shows exactly 80 characters of text, and cuts things off after that.

(This is the only example in this list that actually showed up without me looking for it and was one of the motivators behind this post. I had to search for the other examples on purpose while writing this.)

Here is a screenshot of the same repo but on sr.ht, viewing the README.md rendered at half-screen-width (half of 1920p unflipped screen, or 960px):

sr-ht-half-screen

It cuts off the 100 character and 120 character rulers, but not the 80 character ruler.

(Full screen cuts off only the 120 character ruler).

So more than 80 characters doesn't work in listings at half screen on a 1080p monitor. That seems inconvenient, at least. What if I put code in a README listing, and my consumers want to view the page at half-screen so they can drag my code and drop it into their terminal?

Lowest Common Denominator

To a first approximation (laptop screens), 80 Characters works everywhere.

Here are some screenshots of my opening of the file ruler.txt in the above column check repository. The red lines and the numbers that accompany them show how different screen widths in pixels.

This one is done with "Noto Mono" font, 12 point size:

ColumnsVsPixels12pt

80 Characters is the only ruler which can be viewed at half screen on a 1080p normal monitor (960 pixels). To get 120 characters, you must at least have 1280 pixels at your disposal, which is fullscreen on some laptops, even still to this day.

This one is done with "Consolas" font, 10 point size:

ColumnsVsPixels10ptConsolas

A width of 80 characters works on flipped 720p screens. It even works with 640 pixels, the width of standard definition video. Very useful, even if you are not screencasting on OBS and want things to "just work" on anyone's screen, ever.

For example, Have you ever tried sharing your screen on Google Meet? by default, Meet scales down the size of your screen to... whatever. You have to really crank the settings for that screen your coworker is sharing to get bigger. Even then, it's hard to see stuff. So it's nice when the co-worker can jack up the size of the font so I can see what's being typed.

A width of 80 characters works in lots and lots of places.

Set It and Forget it

I am a creature of habit. I don't want to keep changing what column width I use from project to project. I want to feel like I wrote code that can be debugged at 2am by some poor soul from ops without being cursed for making it harder to open it up on whatever 12-year-old awful screen is still on the crashcart and hasn't been replaced because "it works fine".

So I stick with 80 characters because I know it will always, always work. Not just for me, you understand, but for anyone who may have to look at my code, whether over screen share, default terminal settings, or anything else.

What About Line Breaks

As linked to above, Linus Torvalds believes too many line breaks can cause issues with readability. He implies that defaults don't matter to readability. He talks about the width of terminals being 80 characters only by default, and that "you can just change that setting" so that his code is visible on your screen again. He thinks code that is more readable on his screen is more readable code, and that you should just change your screen to match. He argues that this departure from the default of 80 characters is justified because too many line breaks creates problems in code readability.

I think line breaks are better anyway, if they are done right, as a way to separate concerns. It is possible to make things readable on everyone's screen, and still have this rule improve code readability overall.

Consider this example from one of my old Dockerfile scripts.

Which is better?

This?

RUN yum install -y \
    jq \
    time \
    ruby ruby-devel rpm-devel rpm-build \
    gcc gcc-c++ make patch git zlib-devel glibc-devel && \
    yum clean all && rm -rf /var/cache/yum

Or this?

RUN yum install -y jq time ruby ruby-devel rpm-devel rpm-build gcc gcc-c++ \
    make patch git zlib-devel glibc-devel && yum clean all && rm -rf \
    /var/cache/yum

The first one uses line breaks as a way to separate concerns. The second one line breaks at 80 characters only reluctantly.

Line breaks, early, often, and used as a way to properly break up ideas, are helpful. A limit of 80 characters helps to write scannable code. I've heard this style of embracing short lines called vertical coding. Code that is 80 characters wide encourages simpler statements, smaller functions, and lower cyclomatic complexity.

Admittedly, this isn't why I code at 80 characters. I do it so that my code is legible in every reasonable setting on anybody's screen. However, it does show that keeping my code within 80 characters doesn't detract from my code's readability; rather, it adds.

Just Do It

Observing a width of 80 characters is courteous. It says that other people matter. It acknowledges that communication is about making it easy for others to understand the message, rather than requiring them to work hard to understand.

Once it becomes a habit, it is second nature. Just do it.

Editor Configurations

80 characters in (Neo)Vim

To ensure NeoVim helps me achieve my goal, I set the following in my vim init:

 " guard against 80 character length lines.
hi clear OverLength
hi clear ExtraWhitespace
hi ExtraWhitespace ctermbg=red guibg=red
hi link OverLength Error
match OverLength '\%>80v.\+'
2match ExtraWhitespace '\s\+\%#\@<!$'
if exists('+colorcolumn')
    set colorcolumn=80
else
    au BufWinEnter * let w:m2=matchadd('OverLength', '/\%>80v.\+/', -1)
endif

80 Characters in Emacs

Back when I used to use Emacs, I asked my editor to help me remember the 80 character rule thusly:

;; 80 characters, people.
(require 'whitespace)
(setq whitespace-style '(face empty tabs lines-tail trailing))
(setq whitespace-line-column 80)
(global-whitespace-mode t)