Asking Good Questions

Dan Abramov
7 min readJul 4, 2016

--

I receive programming questions on Twitter, GitHub, email, and other channels. I try to answer them when I can. Lately I haven’t been able to do that very well because I’m a human and don’t scale.

For personal questions, I maintain an AMA. If you want to know my favorite Pokémon, ask a question or read the answers!

If you have a programming question, read on.

“Hello, World” Questions

If you can’t get React to render a “hello, world” example or if your Redux counter doesn’t update when you press “+” and you’re stuck, you can message me directly on Twitter with that question.

I still encourage you to try asking on StackOverflow and Reactiflux Discord first. I often find that writing up the question makes it clear in my head, and the solution becomes obvious. But if you’re just making first steps and are really confused by something, I can definitely take a quick glance.

Please make sure to share what you’ve tried on GitHub, Gist, or, better yet, a fiddle before asking. This way we can make this a quick interaction instead of a back-and-forth. Otherwise it can be time consuming for both of us, especially due to different timezones.

Is your question more complex than a “hello, world”? Read on.

More Complex Questions

If your question is specific (e.g. something doesn’t work) and more complex than getting “Hello, world” running, please post it to StackOverflow first. I stopped answering such questions directly in messages because every time I get the same question I regret not having a link to my last answer.

If you send me a StackOverflow question in a message or in mentions, I will try to take a look at it and tell you if I can answer it. Which brings me to the next point.

How to Get Upvotes

The tricky part about asking good questions is to strike a balance between sharing too few and too many details. You need to phrase your question in a way that both explains your problem and sounds generic enough that other people find it useful. Browsing popular questions for any given tag can give you a good idea of what this looks like. It is a challenge! But if it is hard to ask a question, imagine what it’s like to answer it.

Nobody likes to invest 5 minutes into reading a question only to realize that it omits the part of the code that is crucial to understanding the problem. However, it is equally frustrating to read through 500 lines of code most of which are irrelevant to the issue.

It takes experience and care to ask good questions. You’ll get better at it. For now, it is enough that you make an effort. Here’s how I do it.

Isolating the Issue

Take the code that you have issues with, switch to another branch, and start removing parts that you suspect are irrelevant. Are you seeing the issue with a particular component? Render this component on the page alone. Is the issue still reproducible? Good. If not, bring the removed parts back one by one until you see which one causes the issue. Then isolate that part.

Next, remove all the irrelevant details from the buggy module itself. Keep removing the styling, markup, and business logic until the issue no longer reproduces. Eliminate as many dependencies as possible. Get to the absolute minimum code necessary to reproduce the issue.

Don’t forget to commit regularly! Otherwise you might remove too much and the issue might no longer reproduce. Make sure you always have a breadcrumb trail of what you have been doing.

Finally, try to recreate the issue in another environment. It’s handy to have a “base fiddle” using the same libraries as your project does. This way you can quickly create small independent snippets of code and paste the relevant parts of your project into them. There are some new services similar to jsfiddle but that provide access to npm modules. In particular, I heard good things about WebpackBin and ESNextbin. Check them out!

Most importantly, don’t give up too easily. There is a reason behind every issue. It can be a bug, a typo, or just a misunderstanding. Take comfort in the thought that this reason exists, and keep eliminating possible causes.

Experts often don’t know the problem any better than you. What they learned is not to trust themselves. They dig deeper and keep reducing the test case even if nothing obvious jumps at them for several hours. They know there is a problem somewhere, and finding it is a boring, mind-numbing but usually finite process.

If you’re debugging a problem late in the evening, drop it and sleep on it. Sleep deprivation makes it far too easy to miss typos and other simple mistakes.

You shouldn’t drive yourself to the point of despair either. If you’re stuck and you’ve exhausted your patience trying to isolate the problem, ask for help.

Linking to GitHub Projects

If you have no luck recreating the issue in a fiddle, it is fine to link to a GitHub project from a StackOverflow question. The chance that you will get a good reply is considerably slimmer but it’s worth trying as the last resort.

Here’s a few tips to make your chance of getting a good reply higher:

  • Delete any unrelated files from the repository. Your project should build but if there is just one screen you’d like people to look at, delete all the others. You still need to trim down the reproducing case even if you share it on GutHub.
  • Make sure all dependencies are specified in package.json. Imagine somebody wants to help you so much they clone your project, wait 15 minutes for npm install to finish, and then realize the project won’t start due to unspecified dependencies. To mitigate this, delete node_modules, run npm install yourself, and make sure the project starts swimmingly. If you forgot a dependency, add it to package.json and try again until it works.
  • Make sure npm start will start your project. You can control what npm start does using the scripts field in package.json. It could be something as simple as “start”: “gulp”. The important part is that the person answering the question shouldn’t have to guess your bundler or task manager. All such tools should be dependencies in package.json.
  • Don’t assume other people have Grunt/Gulp/Webpack/Browserify installed globally. You might have run npm install -g grunt at some point but many people don’t do this, or have different versions. Use npm scripts so that you don’t need to ask people to install and run global commands.
  • Provide clear instructions to reproduce the issue in README. This is crucial. There is nothing like cloning a project, installing it, running it, opening it in the browser, and then having no idea how to reproduce the issue, or what the expected behavior is. Instead, you want to specify the exact sequence of steps (e.g. “npm start, open browser at this address, click on this button, I expected X to happen but Y happened instead”).

It is also a good etiquette to never delete the repository if you used it in a StackOverflow question.

Abstract Questions

Finally, there are a few questions that I can’t really give a good answer to.

“What is better, X or Y?”

Unless I used both of these solutions (highly unlikely), I’m not qualified to answer. Even if I used them both, the most I can share is a personal anecdote, not a verdict. My experience will be very specific to the project that I worked on. It is most likely outdated and might not apply to your project because we had different constraints and requirements.

Another problem is in the way this question is phrased. I always feel like the person asking it is trying to avoid a technical decision by delegating it to an “authority” (me in this case). I refuse to be an authority and I don’t want to be held responsible for other people’s choices. People also drastically overestimate how much I know. I’m clueless about a wide range of topics.

Instead, you can ask: “Have you worked with X or Y? If so, did you like either?” If I reply “No, but X looks cool” it doesn’t mean the project is good for you. It just means I liked its README.

Does this sound like useless advice? I think it is! The only way to find if something works for you is to create a small project with it, not to ask me about it.

“What are your thoughts on X?”

If I’ve never used X, I don’t have any thoughts on it besides “I kinda like it” or “I kinda dislike it”. Neither will be very useful to you, and knowing my opinion might even discourage you from going with a good choice. You have much more context about your problem than I do.

If I used X, I have more impressions than I can fit in a tweet. I don’t quite understand how to respond to this question on Twitter. I could write an essay in response but this would quickly become a full-time job.

If you’d like to engage me in a discussion about X, I’m happy to participate if I’ve used it. But let’s talk about something specific, not “my thoughts”. My thoughts are not interesting. Instead, I would like to hear about your experiences using it.

Finally, perhaps you built X. This is awesome! Help me and others understand what it is and why you built it. Explain not just what the API looks like, but how and why you are using it.

README is the best place to do this. Your tweets to me will get lost tomorrow. As much as I’d like to help, I probably don’t understand your use case well enough so my opinion won’t be very useful to you. Instead, seek out the people having the same problem, and ask their opinions.

Wrapping Up

Try to put yourself in the shoes of the person answering the question. You might discover that some questions are impossible to answer, or that you could have spent more effort crafting the question to get a better answer. Let’s value each others’ time and have more high quality conversations!

--

--

Dan Abramov

Working on @reactjs. Co-author of Redux and Create React App. Building tools for humans.