[HN Gopher] Rules for Writing Software Tutorials
       ___________________________________________________________________
        
       Rules for Writing Software Tutorials
        
       Author : mtlynch
       Score  : 78 points
       Date   : 2025-01-02 14:23 UTC (8 hours ago)
        
 (HTM) web link (refactoringenglish.com)
 (TXT) w3m dump (refactoringenglish.com)
        
       | mtlynch wrote:
       | Author here.
       | 
       | I've been thinking for a long time about anti-patterns I see when
       | following software tutorials, so I put together this list of
       | things I think differentiate good tutorials from poor ones.
       | 
       | I'm happy to hear any feedback on this list or hear about other
       | things I should include.
        
         | MortyWaves wrote:
         | I actually don't like the example with Djano and JS: too much
         | bad/fake SEO compounded by Googles enshitification mean that
         | very specific search terms for specific technologies get
         | drowned out by generic word salads like "organising and
         | structuring djano projects".
         | 
         | There's probably a million of those already.
        
           | mtlynch wrote:
           | Thanks for reading and for the feedback.
           | 
           | Yeah, I see what you're saying. I had this article[0] in
           | mind, which is a well-written article and ranks #1 for
           | "organize front end code django" on Google. None of the other
           | results are close in relevance or quality.
           | 
           | But I guess that example could be confusing for readers who
           | aren't familiar enough with Django to know why structuring
           | the frontend is a hard problem that not many people write
           | about.
           | 
           | [0] https://www.saaspegasus.com/guides/modern-javascript-for-
           | dja...
        
         | jackpirate wrote:
         | I have a minor nit to pick. I actually prefer when tutorials
         | provide the prompts for all code snippets for two reasons:
         | 
         | 1. Many tutorials reference many languages. (I frequently write
         | tutorials for students that include bash, sql, and python.)
         | Providing the prompts `$`, `sqlite>` and `>>>` makes it obvious
         | which language a piece of code is being written in.
         | 
         | 2. Certain types of code should not be thoughtlessly
         | copy/pasted, and providing multiline `$` prompts enforce that
         | the user copy/pastes line by line. A good example is a sequence
         | of commands that involves `sudo dd` to format a harddrive. But
         | for really intro-level stuff I want the student/reader to
         | carefully think about all the commands, and forcing them to
         | copy/paste line by line helps achieve that goal.
         | 
         | That said, this is an overall good introduction to writing that
         | I will definitely making required reading for some of my data
         | science students. When the book is complete, I'll be happily
         | buying a copy :)
        
           | mtlynch wrote:
           | Thanks for reading!
           | 
           | > _Many tutorials reference many languages. (I frequently
           | write tutorials for students that include bash, sql, and
           | python.) Providing the prompts `$`, `sqlite >` and `>>>`
           | makes it obvious which language a piece of code is being
           | written in._
           | 
           | I think it's fine to show the prompt character, but I think
           | it's the author's job to make sure that copy/paste still
           | works. I've seen a lot of examples that use CSS to show the
           | prompt or line number without it becoming part of copied
           | text, and I'm highly in favor of that.
           | 
           | I think if I had to choose between breaking copy/paste and
           | making the language obvious with the prompt character, I'd
           | exclude the prompt, but I think that's a matter of taste.
           | 
           | > _Certain types of code should not be thoughtlessly copy
           | /pasted, and providing multiline `$` prompts enforce that the
           | user copy/pastes line by line. A good example is a sequence
           | of commands that involves `sudo dd` to format a harddrive.
           | But for really intro-level stuff I want the student/reader to
           | carefully think about all the commands, and forcing them to
           | copy/paste line by line helps achieve that goal._
           | 
           | Yeah, I agree about preventing the reader from copy/pasting
           | something dangerous.
           | 
           | In tutorials that require a reboot, I'll never include a
           | reboot command bunched in with other commands because I don't
           | want the user to do it by mistake. And I agree for something
           | like `dd`, you'd want to present it in a way to make it hard
           | for the reader to make mistakes or run it thoughtlessly.
        
       | ctkhn wrote:
       | Very good stuff. Going to consult this as I build personal and
       | work projects. Working at a huge org right now and its amazing
       | how many crucial details are missed in the tutorials that we have
       | for internal things we depend on
        
       | indentit wrote:
       | I really like how clear and well laid out these rules are. It
       | covers lots of things that I have always thought about when I
       | write instructions in README files etc, so it's very nice to see
       | everything neatly described/reasoned in one place. Thanks for
       | sharing!
        
       | alentred wrote:
       | Extending on the copy-pasteable snippets, another big improvement
       | (flaw to avoid) is to include all imports to the code snippets.
        
       | stared wrote:
       | There is a lot of good advice about details!
       | 
       | Especially one that got my heart:
       | 
       | > Some authors design their tutorials the way you'd give
       | instructions for an origami structure. It's a mysterious sequence
       | of twists and folds until you get to the end, and then: wow, it's
       | a beautiful swan!
       | 
       | > A grand finale might be fun for origami, but it's stressful for
       | the reader."
       | 
       | Yes, a lot of tutorials are puzzle games. You need to guess other
       | tools to install, which are obvious to the author, but not
       | everyone.
       | 
       | I would add a few things:
       | 
       | * Have two types of examples - minimal and the most typical (one
       | is to show the essence without distraction, the second to serve
       | as a practical starting point) * Always provide the full code
       | sequence to run code; if there are any assumptions, these should
       | be listed explicitly (e.g. "it needs Node 22"); you hinted a bit,
       | but since many tutorials miss that, it deserves attention.
       | 
       | Even better, if it is possible to combine it into one point and
       | make it runnable. For example, for a package I had been
       | developing, livelossplot, I made Jupyter Notebooks runnable in
       | Colab:
       | 
       | * https://colab.research.google.com/github/stared/livelossplot...
       | * https://colab.research.google.com/github/stared/livelossplot...
        
       | jagged-chisel wrote:
       | I thought "Keep your code in a working state" would be discussing
       | how to keep code working when some dependency changes. What was
       | covered is valuable advice, but I'd like some exploration on
       | keeping the published code cohesive under refactoring and
       | refinement away from the text.
       | 
       | For example, if I'm P. Shirley and I've written a book (with
       | code) about following light rays between a virtual camera and
       | virtual objects. I have refactored some code to be more clear. Of
       | course, I have iterated on this code to verify it remains
       | correct, but the related text isn't affected. I have to remember
       | where to paste this new code. Unless the documentation had some
       | kind of reference to the specific file, lines, and/or function to
       | render into the text.
       | 
       | What's the advice for best practices here?
        
         | amenghra wrote:
         | Some people embed code in a way that's similar to a test and
         | then have a process to run/test all the embedded code.
        
         | smitty1e wrote:
         | Given that most examples are relatives small, one could
         | leverage org-babel[1] and write the tutorial with executable
         | code, and go straight to .PDF!
         | 
         | [1] https://org-babel.readthedocs.io/en/latest/
        
         | joshka wrote:
         | Make the tutorial text include the code verbatim from a working
         | repo that passes CI. No pasting necessary. Sure you still have
         | to verify that the tutorial text aligns with the code changes,
         | but you don't have to do anything manual to update the code in
         | the tutorial.
         | 
         | As an actual example of this, here's a plugin for Remark that
         | allows us to import specific functions from a rust source file.
         | https://github.com/ratatui/ratatui-website/blob/main/src/plu...
         | If the source code fails to compile, we get a CI error (in the
         | rust checks). If the source code changes in a way where the
         | import is no longer correct, we get a CI error (in the npm
         | checks).
        
       | rinvi wrote:
       | Thank you for this. I want to also reference diataxis [0], a
       | systematic approach to technical documentation authoring, which I
       | think has some good advice on the subject of tutorials.
       | 
       | [0] https://diataxis.fr/tutorials/
        
       | rglover wrote:
       | This is a great list of stuff. I spent years writing tutorials
       | and wish this list existed when I first started.
        
       | edihasaj wrote:
       | Great
        
       | Linux-Fan wrote:
       | I am rather ambivalent about these rules. I disagree with a lot
       | of the individual points, but I am also sure that I have probably
       | often written bad tutorials myself where some of the rules would
       | have clearly helped... :)
       | 
       | > 5. Make code snippets copy/pasteable
       | 
       | I like to use the prompt to identify the language and also the
       | user (root `#` vs. user shell `$`) to perform the action under. I
       | advise against copying random commands off the internet
       | especially those that run as root and may break your system (like
       | `apt` and `--yes` together...). Of course, today, it is often
       | assumed that you have sudo setup and then `sudo ...` is used to
       | indicate the use of root privileges. It is an interesting
       | convention although in my opinion this sometimes hides the actual
       | intent.
       | 
       | I prefer:                   # echo 3 > /proc/sys/vm/drop_caches
       | 
       | over                   echo 3 | sudo tee /proc/sys/vm/drop_caches
       | 
       | The example given in the article is exactly one where attention
       | is required: It adds a PPA as root, thereby giving "full control"
       | to the PPA author. Never straightout copy-paste such stuff.
       | 
       | > 6. Use long versions of command-line flags
       | 
       | I am so much more used to the short versions hence I prefer `grep
       | -RF` over `grep --dereference-recursive --fixed-strings`. Also,
       | my go-to documentation about these commands (POSIX) doesn't even
       | know about the long options.
       | 
       | I know that the advice to prefer the long options is repeated
       | pretty often so it might just be me :)
       | 
       | > 7. Separate user-defined values from reusable logic
       | 
       | Ever followed some "enterprise-grade" software setup tutorial?
       | Sometimes they start by assigning 20 variables to some generic
       | values that you don't change most of the time and then go about
       | to reference them on the next 20 pages or such making it close to
       | impossible to know what is really going on. Also I find that for
       | simple cases this greatly complicates the input process.
       | 
       | I think the example doesn't really show the difference because it
       | has some variables (just not in shell syntax) in the code already
       | like `YOUR-API-TOKEN`. Of course it is better to write
       | `$API_TOKEN` rather than `YOUR-API-TOKEN`. I often prefer to see
       | the example value in the example i.e. not `YOUR-API-TOKEN` but
       | some real string (if feasible). In many cases I won't change a
       | value in the beginning to see how far I get with a "known valid
       | input". Also, I often prefer to pattern-match some real value
       | against what I have available, e.g. I have a key which I think
       | could be the API key but if the format is totally different from
       | the tutorial I may realize that this is an "app token" rather
       | than "API key" and that I may need to get a different value if it
       | fails to run with my input or such.
       | 
       | > 9. Let computers evaluate conditional logic
       | 
       | If dosed correctly, I think this is good advice. I'd strongly
       | prefer the conditional boxes from the "bad" example over the
       | "good" monster shell script command. In my opinion a tutorial
       | shouldn't optimize for speed of execution but rather foster the
       | understanding by the reader. There is no help if I find this post
       | 10 years later and it helpfully outputs "ERROR: Unsupported
       | platform" on my Debian 16 system. If the text instructions are
       | given as in the "bad" example, I quickly realize that all of this
       | is outdated and I should probably try with the most recent
       | package name (example-package2) rather than meddle with some
       | script.
        
       | baudaux wrote:
       | > As soon as possible, show a working demo or screenshot of what
       | the reader will create by the end of your tutorial.
       | 
       | For this reason I am building a new way of writing coding
       | tutorials, with the possibility of writing and running code
       | snippets into the web browser including graphical apps:
       | https://exalib.com
        
       | codetrotter wrote:
       | > Tutorials often forget to mention some key detail, preventing
       | readers from replicating the author's process.
       | 
       | I also find this sometimes.
       | 
       | A high quality tutorial on the other hand, is often one where the
       | author bothered to set up a fresh VM and follow their own guide
       | step by step to confirm that everything works as described. This
       | way the author avoids unintentionally forgetting to mention
       | additional dependencies that have to be installed and additional
       | config files that need to be tweaked in order for the steps to
       | work.
        
       ___________________________________________________________________
       (page generated 2025-01-02 23:00 UTC)