"Tutorials" is a very broad term. It covers different levels of detail designed for folks at varying levels of expertise. For purposes of these guidelines I'm narrowing the consideration towards beginner level web tutorials designed to teach a reader who has enough prerequisite knowledge to follow along but no significant experience in the tutorial's topic.
Furthering the scope definition, I love the way documentation.divio.com splits documentation into four categories: tutorials (oriented towards learning), how-to guides (to solve a specific problem), explanation (adding in depth understanding), technical reference (the source of all the nitty-gritty details). While these guidelines can apply to all four styles, the focus is on the learning-oriented tutorials.
These are drafts. I'm stating the guidelines declaratively, but I'm still playing with them. They'll change. In some case may not hold up at all.
There's no pedagogical research behind this. It's all based of my experience. I have a couple of decades experience programming. So, I'm hardly a beginner, but I've been learning a bunch of new stuff recently. That gives me a pseudo-beginner perspective that I'm hoping can help bridge the gap back to folks earlier in their journeys.
Not all guidelines will apply to all tutorials. (For example, the parts about style sheets won't be involved in tutorials on setting up serverless functions.) Some guidelines may even apply to one part of a tutorial but not another. Consider these tools in a toolkit. Not a set of parts that all have to be used like you would putting together a piece of furniture.
I'm not kidding about this being a draft. There are spelling and grammar errors floating around. The order of things is arbitrary too. I'll get to all that once I get the ideas down.
Remember, these are guidelines, not rules. Think Happy Path, 80/20 type stuff. Not an attempt to define the immutable laws of tutorial physics.
TODO: Expand the examples with code snippets
TODO: Shuffle things into a better order
The Guidelines
Define the goal
Make a clear, one sentence goal and write it down. If it takes more than one sentence, consider breaking things down into multiple smaller tutorials. They can be split out like chapters in a book, but keep the starting and ending points for each well defined and independent. Think separation of concerns.
Make sure the goal is learning
The goal is not to get something done. The goal is to each a reader how to do it. That said, they don't need to walk away an expert. The goal is to move them up a run on the learning diagram (TODO: find a good link for the Dreyfus model of skill acquisition or similar). Said another way, they don't necessarily have to know why they are doing a thing, just that doing the thing gets the result they're after.
Show every step
Don't throw nineteen lines of code at the reader in one go with little more than a "just do this" type instruction. The goal is not to get something working. The goal is to teach the reader how to do the thing . Detail changes step by step so that folks who are earlier in their journey have the most support. Provide context and explication for each line. (The Step by step example I'm playing with is an example of this. There's work to be done on the interface to get descriptions closer to the code, but the concept feels right.)
Build wrappers, then fill them
Matching brackets, braces, and parenthesis is hard. When demonstrating code that contains when (especially things like react onClick handlers that have multiple closing elements stacked next to each other), place an empty wrapper first with nothing but the opening and closing fence posts. Add the content in the following steps.
Create the if/else in one shot
Not sure about this one yet, but the idea is a follow on to building wrappers first. The extension here is that you would build both elements of the if/else and then fill them. That might not work all the time, but it's something to investigate.
Just show me the way to do it that I'm going to actually use
This one gets me all the time. Tutorials have a bad habit of showing one way to do something then saying, "but no one does it that way, everyone uses this shortcut". The idea behind that approach is to provide more context, but it works at cross purposes. I dont have the context to make the contextual leap between two new things without having worked with them first. So, what happens with that approach is that I spend mental energy working to learn something that I'm not going to use. Just show me what I need to actually be working with. If I run into a situation where I need to use the full thing I can deal with that when I get there and I'll have an understanding in place that
Don't put in code you're going to remove
his is related to just showing me the way I'm actually going to do it. I've hit several tutorials where you put in some code only to take it out a step or two later. The happy path for a learning tutorial is only to add code. Show me the one way to do it. Don't make me send mental energy setting things up one way only to flip to something else that I have to burn more mental energy on to replace.
Pick a single path
Don't offer multiple ways to do something. For example, at the start of the React Router tutorial it says "Feel free to use your bundler of choice like Create React App or Vite." I don't have enough information to make that choice which causes a break in what I'm trying to do and a lack in confidence. Just pick the Happy Path and go with that. If there's a large possibility of different options being used. Pick one to start with and then offer the other ones as options with "if X doesn't work for you our you already have Y installed, you can use it instead like..."
Default to over-explaining
folks can skim if they already know what's up, but beginners can't magic the knowledge out of thin air if it isn't on the page.
Setup the scaffold one time and get it out of the way
For example: don't put inline CSS styles or classes in tutorials that aren't about CSS. Make a single .css file for the reader to copy and paste at the beginning that uses elements instead of classes and have them put that in place and then ignore it for the rest of the tutorial.
Consider not applying any styling
For tutorials that aren't focused on CSS, how much is gained by styling compared to the visual and mental overhead it required.
Label all the things
Every code block should start with an indicator line that either defines the file it's for or states that it's a command for the terminal
Don't try to pull double duty
For example: even though a Windows version and Mac version of a tutorial might be mostly the same, they should be split to two separate things instead of sprinkling in "if you are on windows do this but if you are on mac do that" statements. Each one of those is noise for users of both operating systems. When were learning we look closely at everything and we ended up wasting energy parsing through that friction because we don't know if there's something we need in there or not.
Don't add two of the same thing at once
For example, in the React Router tutorial the section on adding routes has the reader add two routes at the same time. Adding one at a time reduces the size of the change and will have a more direct connection to the change. (Change one thing, see one change.) Adding the second thing as its own step also provides a better practice type reinforcement since the reader will know what to expect and can map their new knowledge onto what they are doing.
Match syntax highlighting
An ideal design would set a sane default for code syntax highlighting then allow the reader to switch to whatever theme they are using so what they see in the tutorial matches what they see in their editor. (This would include the ability to turn off syntax highlighting for folks that are working without it.)
Separate deletions and additions
The goal is to avoid adding code that's later removed but there will be times when that's appropriate. In those cases, make the deletion of code it's own step instead of trying to show an add and delete at the same time
Almost always be compiling
Whenever possible, the app should compile and run at the end of every step. When not possible, let the reader know in advance that they are going to see an error message.
Explain the error
When you have a step that causes an expected error break things down into two parts. The first is the change that produces the error (letting the reader know it's about to happen). Then, explain the error (and how to read it) in an independent follow up step.
Better broken than overwhelming
(TODO:combine with Explain the error) - If it requires a bunch of code to move from one working state to another with added functionality, break it into smaller steps that may include ones where the app doesn't compile/run or just generally errors out. Introducing those errors is fine given how much time we spend looking at them. It's also better to put an intentional error in front of someone so they are ready for it and you can explain it than to through a bunch of code at them with the highly likely result being a typo and an error message they have to troubleshoot themselves without context.
Show as little as you can get away with
There's a balance to showing as much as needed, but the direction should be to focus in as much as possible on just the lines that need to change. Other guidelines (like avoiding styles and creating wrappers then filling them) can help with this.
Idea: Content comment markers
For tutorials that require bigger sections of code, what about having the reader put in comments to identify sections. Not for everything, but just the main parts or enough to help scope down so examples are easier to pinpoint.
Don't show incorrect line numbers
For example: The Adding a No Match Rule section of the React Router Tutorial has a code snippet showing the addition to a 'src/main.jsx' file. The snippet starts at line number one, but the code is actually further down in the file. (You can see an earlier version with the full contents of the file in the Nested Routes section.