Developers August 5, 2020

Do you write TODOs in your code?

Matthew Freire @mattfreire

Consider answering the poll at the bottom of this post 👇


This is an example of a TODO written in Python code:

def my_function():
    # TODO Fetch data from the API and render it
    return

I think there are a lot of reasons why I don't do this:

  1. I forget about them. Even though there's a TODO tab in Jetbrains IDE's, I barely look there.
  2. They don't normally contain useful information because they're so short (1-2 lines, anything more feels like a punishable offence).
  3. They behave more like a reminder. To me, TODO's normally invite discussion, categorisation, and have to be planned within the larger scope of the project.

But there's one reason why I think most people do it:

It's so convenient

How often do you write TODOs in your code?
  1. 4

    I stopped writing TODOs unless I create a ticket for it. Because it gets lost and it is never planned to resolve.

    But, if I add something like
    // TODO [TICKET-ID] improve performance here

    then it will have higher chance of being actually done

    1. 1

      I like that workflow. Do you use any other software for keeping track of the ticket?

      1. 1

        it depends on the team I'm in. Kanbanize, Trello, Jira, whatever.

  2. 3

    I use an extension on VScode that let's me see all the //TODO: items I've commented in code quickly :)

  3. 2

    I mainly use TODOs for technical tasks within the codebase. Features, bugs, etc. could have some associated TODOs, but those should have their source of truth in the project management tool.

    I have a relatively unique technique that I picked up from an old manager. The format goes:

    // TODO: [PRIORITY 0-9]. [OPTIONAL TAG] - Description of TODO

    Priority 0 means "fix before committing" and I actually use this a ton. I can't count the number of times I've seen someone (myself included) stub something out and forget to fully implement it, or leave unnecessary debugging code in, etc. This prevents those kinds of mistakes, and let's me feel confident that when I leave one area of code and come back to it later that I've implemented and cleaned up everything I meant to.

    Priority 1-3 is "high" - Should probably do something about this very soon, may be worth it's own ticket in the project management tool.

    Priority 4-6 is "medium" - We could leave this or take it. This is great for algorithm optimizations where you're like "this clearly can't be the fastest/best way of doing X, but it works and that may be sufficient". When you or someone else comes back to the code later they can be like "oh! yeah that other algorithm is more complex to implement, but it is really needed here"

    Priority 7-9 is "low" - These often will never get done and probably don't need to get done. But it satisfies that internal "hey this could be slightly better and I need to write that down somewhere" itch. And, when you're refactoring or implementing a new feature it can be good to use as reference on minor things you can improve as you're doing that.

    The tag is great for indicating the feature a TODO goes with, or for marking it with a ticket number.

    Also I'd say don't be afraid of "long" TODOs. Especially ones you won't be dealing with right away. Make sure future people reading them have an idea of what's going on. "Fix this" is utter garbage. I usually aim for 1 line but if it spills over to 3 or 5 I don't beat myself up about it. I'd rather know everything I need to know when I come back to the code.

    As some examples:

    // TODO: 0. Revert this test code and use live data.

    // TODO: 1. This will likely be too slow on production data, review data and fix before merging.

    // TODO: 5. DATA - We should find a better way of exposing this data to this part of the application. This feels overly complicated and error-prone.

    // TODO: 8. It'd be cool if we could pull in Tim's new styles here for extra consistency.

    I've found this to be a really useful way of using TODOs so hopefully someone else here will find it useful too!

  4. 2

    I will add a TODO when I have broken up work, and I have an explicit plan to add something later. If I can't point to the task where I will DO it, I don't add the TODO. For example, if I'm adding a new UI feature that needs some plumbing, I might break it into two phases:

    1. The plumbing, with a TODO to fill out the UI
    2. The UI pieces

    There are other ways you can semantically indicate within code that something needs to be done:

    • Put a NOTE or N.B. in the method description: these inform the user that there's a caveat for using this code
    • Put an inline comment at the site. For example, something that calls a loop out as being quadratic that could be linear with a lot more bookkeeping.

    If it's important enough to do later, it should have a ticket/task/bug/whatever and be prioritized against the rest of your project. If it doesn't even rise to that level, then why bother recording it?

    1. 1

      Do you keep them only in your code? Or do you like to keep track of them in something like Trello as well?

      1. 1

        If it's kind of technical thing, like refactoring, I mostly keep them in my code.

        If it's more like a feature then in my todo app.

  5. 2

    I use them during development, but ultimately remove them. If a thing is valuable enough to be worked on, it needs its own ticket/issue. Otherwise it gets lost for months or even years. Which probably means that it was not valuable at all in the first place.

  6. 2

    I use TODOs, FIXMEs, and a to-do list.

    TODOs are just little notes in the code to remind me of why a particular thing isn't complete. I try to make sure they aren't crucial things… usually just minor refactors, or ideas for how I can make something more efficient or add cool functionality.

    FIXMEs are comments I leave in the code to denote something crucial. For example, if I comment out some code for testing purposes, I'll add a FIXME comment to remind myself to come back and uncomment it. I've set up Git to prevent from committing and deploying any code that still has FIXMEs in it.

    Finally, I have an actual to-do list in Notion where I keep a list of features to build, bugs to fix, interactions to improve, etc. It's mostly an archive so I don't forget things, and I occasionally look at it to decide on my next task.

  7. 2

    Hi Matthew! Very cool you bring this up. Checkout my project when you get a chance https://qwoka.io :) Working on bringing visibility and integration for TDODs and notes embedded in source code across multiple projects. Let me know what you think.

    1. 1

      That's very cool. Seems I'm not the only one who had an idea like that! Will be happy to try out the beta.

  8. 2

    I leave them as a memo while I work in a feature branch. But I prefer to move them into a project backlog before making a Pull Request (or merge).

    In a backlog of a project tracker, you have much more capabilities: leave a comment, enhance description with links and screenshots.

    And I more tolerant of a pile of tasks in a backlog than a TODO here and there in a codebase.

  9. 2

    Yep, constantly use them. Usually, for things I know I'll have to implement but aren't part of the immediate task. One example is always // TODO: Authorize action

  10. 2

    I use TODO comments all the time! They're a very important part of my workflow. A couple things enable this for me:

    • I have a keybinding in my editor (Emacs) for adding a new TODO comment to the next line. The real nice thing about it is that it works in any language, instead of just naively prepending // or # or something like that. Happy to share this with other Emacs-users if anybody is interested!
    • I use magit in Emacs as in interface for git, and I have an addon for it called magit-todos. Whenever I visit the view to interact with git (commit, push, pull, etc), I see a list of all of the TODO comments in the codebase, and a separate list of all of the TODO comments that have been added since branching off of master. So there's no overhead for me in having to visit a separate tab, or do a manual search for the comments - they're right in my face many times a day.

    I do strongly recommend this workflow. Being able to quickly drop a TODO comment down knowing I won't forget to pick it up later allows me to offload a ton of cognitive burden.

  11. 1

    I use TODO for stuff on a PR that I have to resolve before putting it up for review and FIXME for stuff I want to defer working on until some time in the future. It has worked well. Sure they get forgotten about occasionally but they are not business critical and often work themselves out eventually but nice to have the context there.

  12. 1

    I do, for many years.

    But also I worked in a company where we wrote issue# of a bug and decription in automated tests when we found bugs.

    Then I had a script that parsed automated tests and extract all the ToDO's and Bugs that we marked in the tests. For bugs the script would check if our core team fixed the bug or not (via github API) and mark it in report. That way anyone could check what needs to be tested if the fixes implemented are working or not and if they do we removed the issue# comment from code and the next day when the tests run the issue was removed from the reports too.

    Very efficient ;)

  13. 1

    // TODO – Don‘t forget to comment

    It happens pretty rarely. But when such a comment appears something very important is missing.

  14. 1

    It depends what you intend them for: the example you have shown almost smells like function documentation; instead, if you intend them as proper todos, then you should not forget about them :)

  15. 1

    I like them for handoffs.

  16. 1

    I almost never do it, but when I do, I would resolve it within the next few hours.

  17. 1

    Nothing wrong with it - as long as they're TODOs that add value to the software and are not required to ship. Sure - you can pollute your github issues or make JIRA stories for them, but I think the point of a TODO is to come back to this line of the commit and make a change in the future. My issue with putting TODOs in other places than in code is keeping pointers to the actual line; also if some other developer moves the code or refactors it, the reference is gone.

  18. 1

    I never use it. I think that if something is needed should have its own ticket in your to-do list. Maybe you could use it if you have an extension that list them all and you include that in your workflow

  19. 1

    Does using Rust's unimplemented count?

    Other than that case, where I have to write unimplemented!() to even compile the module, I generally don't very often.

  20. 1

    I write to do in the code but usually only when the IDE does a code analysis before committing to source control like phpstorm does. That way I don't forget to do something or where it needs to be done. I tend to put the to-do in my actual to-do list as well outside of code such as Trello

    1. 1

      And how well do you keep those two lists synchronised? I find myself forgetting about code todos, or forgetting about Trello, or both 🤦‍♂️

      1. 1

        Usually when the IDE reminds of a to-do I delete it in the code when I start working on what's needed and then when complete I find the corresponding to do in Trello and mark it as done so usually they stay in sync.

  21. 1

    Never! I keep a notion “Tasks” table for each codebase I work on. It’s always open in the background and I write even the most minor changes there. I don’t think it disrupts my flow!

    1. 1

      I guess it's a matter of getting into the habit of opening Notion every time you start working. That way you'll get used to switching to the browser and back every time you write a TODO. But honestly, this sounds better than writing some todos in code and forgetting about them.

  22. 1

    For me, TODOs are usually just another code comment. It's nice when a fellow dev colleague opens the file where she expects a bug or origin of an issue, and there is a comment pointing out that very issue, instead of having to go through the actual code and understand what it does and what not.

    Sometimes, I'll also put a TODO which I will actually resolve, usually when I work on a feature over a longer span than a day. That way, I know where I stopped and how to proceed.

  23. 1

    Yep I do it quite a bit so I dont have to leave my editor, breaking my flow. The before a launch of the new updates I'll search the code for "TODO" and work through em.

    1. 1

      I'm curious. Do you rewrite those TODOs in a simple management tool like Trello/Notion? Or do you just keep them in the code?

      1. 2

        Yep in the code, this way I dont mess up my "flow state" when I spot something to fix but having to leave my IDE just throws me off.

  24. 1

    This comment was deleted 2 months ago.

Recommended Posts