Show HN: A plain-text file format for todos and check lists

452 points by jotaen ↗ HN
After having cycled through various CLI-based todo apps, I started to realise that I actually don’t need a tool at all for managing my todos. Most of the time, my use cases are quite simple, like viewing my todo items, checking them off, or adding a new one.

Rather than having to memorise CLI commands for these interactions (which I’m not super good at), I figured that it’s easier for me to use my text editor directly, and have an editor plugin help me with the visual structure and some convenience functionality. So, kind-of similar to Emacs Org Mode, but without having to use Emacs. I personally use Sublime Text, and even though I enjoy it a lot, I don’t like being bound to specific tools.

I think the best basis for staying independent is to have a data format that’s properly specified and meaningful on its own. This puts the data first, and it allows the tools to be built on top and shared (or interchanged) more easily.

This is what [x]it! is about, which is a plain-text file format for todos and check lists. I’m curious for thoughts and feedback. There is obviously not much tooling support (yet), but feel free to create something if the idea resonates with you.

Website with demo: https://xit.jotaen.net

File specification: https://github.com/jotaen/xit/blob/main/Specification.md

171 comments

[ 3.6 ms ] story [ 253 ms ] thread
This is really cool. I am endlessly fascinated by the proliferation of "productivity apps" when I find the same thing as you: that they are quite unnecessary.

My approach is similar. I already take notes via a Bash script. I configure a particular "label" for any todos and (essentially) just grep for them, excluding those that are crossed out (with Markdown tildes). This approach works great for me as a Staff Engineer in a large tech company. Reference: https://github.com/scottashipp/noted/blob/main/subcommands.m...

I also wanted to mention there are several related ideas / movements around the web. One of the biggest is todotxt. In case you hadn't heard of it: https://github.com/todotxt/todo.txt

I used todo.txt for a while, but in the end I stopped using the CLI tool and just worked with the files directly. For my use cases, the todo.txt file format has a few shortcomings and inconveniences, and there also is no dedicated specification.

That being said, I drew a great deal of inspiration from todo.txt, and I think it’s a well-made and powerful tool.

This is very cool, thanks for sharing! I'm a huge proponent of tool-less things, and a consistent todo list format readable in any text editor has been extremely helpful for me. I use my own markdown-inspired todo+notes format, but looking through xit and todo.txt has given me some ideas, specifically around my format's[1] inability to indicate priority when a line is taken out of context.

Question: why must the square brackets be used[2]? Could not the first and third chars be omitted, leaving only the status of the item as the first char on the line? I can see (and appreciate!) the desire to use brackets for readability, but if there's a functional benefit I'm not sure I see it at first glance.

I especially like your use of `!` and `#`, that's a nice way to make those items accessible through a grep.

[1]: Each day begins with a `\n# YYYY-MM-DD` section heading, then I use the ordering of my day's tasks in the list to indicate priority. `- ` prefixes an incomplete task, `* ` prefixes a completed task, `~ ` prefixes an obsolete task (similar to your xit), and a generic note doesn't have any predefined first char. One or more pair(s) of spaces indent subtasks or notes as appropriate.

[2]: https://github.com/jotaen/xit/blob/main/Specification.md

> Question: why must the square brackets be used[2]?

There is no technical benefit behind the square bracket notation. As you mentioned, it’s mostly for readability reasons. My take on pleasant plain-text formats is to make use of symbolic notation if ever possible, because that makes the format more intuitive to understand. The `[ ]` resemble a check box, and it should be immediately clear what that means. The drawback is that you need to type in 2 extra characters, of course, so it’s really a tradeoff in the end.

Like you and many others, i use my own similar format, and the brackets actually come in handy for those rare cases when there is a need to print out (yes, as in harccopy paper; oh the humanity)...because they resemble good ol' fashion checkboxes. ;-)
This is awesome! Super appreciate the effort on this.

One challenge I've had is the file-based concept. And it losing "shape" quickly. I taken a few whacks at something different and have settled on a CLI-based kanban-y thing: https://github.com/kitplummer/clikan

But this lacks things like tags - which I appreciate as long as they are searchable in some form.

nb might be worth a look (has tags) https://xwmx.github.io/nb/
I loved nb! Until I ran it from a top-level directory and it committed an update to every git repo within that top-level. :D. Definitely operator error, but I learned my lesson and am back to separating notes from todos.
Cool, that looks quite neat! I agree with you, at some point you have to structure things in one way or the other, in order to keep an overview. For me it works somewhat well to organise my data across different files and folders, which are setup in a certain structure. That either requires some manual labour and discipline, or you automate these workflows. That requires “standardised” data formats, however.
Nice! I also have this pain of the file losing shape quickly. My take is to have a a CLI tool to "carry over" all todos which aren't solved into a new heading. This way the old/resolved items are moved to the back/lower in the file.

I call it Rodo (Todos in Ruby): https://github.com/coezbek/rodo

It uses Markdown for syntax.

It looks great, I'd have to give it a try to be able to have an opinion on it though.

Did you try PlainTasks? You might be able to borrow a few ideas from it too.

Congrats!

Looks interesting. Might be worth looking at the Emacs Org Mode support for TODO lists[1]. Just as a reference for how someone else dealt with TODOs in a text format, but with a pretty complete feature set.

[1] https://orgmode.org/org.html#TODO-Extensions

Great work on this — love the website demo!
> [an item] MUST start at the beginning of a line with a checkbox.

Why no subitem?

    [] large task
      [] subtask 1
      [] subtask2
I use this all the time.
I use subitems pretty heavily in my todo_notes.md file as well; to work around the concern over conflict of state, I pay attention to only the checked status of the `large task`. If that parent is not checked off, I know there are still pending subtasks. So I won't really care if there are un-checked subtasks; as long as the parent task is checked I know I can ignore it and move on. Maybe that could be formalized a bit more strongly but since it's only my eyes which will see my todo 99% of the time, I'm fine with it and I know the convention.
This is very cool!

We're actually building an editor/IDE of sorts from scratch, but specifically for "todo.txt" (https://thymer.com if you're interested). I think a lot of parts of your spec would fit really well with the concepts we were thinking of (like the status in between [ ], due dates, #tags..). Maybe we should add compatibility for this spec as well (for things like autocomplete, and export/import).

Thanks for posting, really helpful for portability to have more standards like these!

I am conflicted on this.

The spec is nice. I love the recognition that dates may be imprecise (e.g., 2022-05 -- although I would count that as the last day of the period, 23:59:59 on 2022-05-31, rather than the first day of the next period, 2022-06-01). I like the thought that went into it and the nice presentation.

On the other hand, I do not think this is necessary or even all that helpful in the real world. You don't need a standardized format if you are writing to do items manually in a text editor. You just write them. In the vast majority of cases no one is going to see them but you. Time spent conforming to a spec is time wasted.

A formal spec also doesn't help much for apps to use this format. There is not a huge need for portability between to do apps, and for most users to do items are ephemeral and not something that needs to be archived and revisited. Even if an app adopted this, being tied to a plain text format would likely hinder feature development, including the ability to sync across multiple devices. Beyond that, different to do apps use different systems of categorization and tagging, so really in practice I doubt this will become any kind of standardized format.

So, all told, it is a beautiful effort, nicely presented, but I think it is unnecessary.

> A formal spec also doesn't help much for apps to use this format. There is not a huge need for portability between to do apps...

To add some counterpoint to this, I try a lot of apps. Partially because I'm always looking for the one that's better than what I use now - looking for the thing that fits me the best - but also because I just like trying things.

Portability means a greater chance that I'll fully dive in and use an app to its potential vs. some light use.

There have been a few times that I've found a new app/solution that was clearly better than what I was currently using, and this was both exciting and frustrating. Frustrating because it meant I'd either have to leave my history behind, or spend a ton of time trying to port it over somehow.

I realize I'm part of a niche group of people, but I feel like a spec like this was meant for a pretty niche group of people.

I for one do not agree that this is unnecessary, but I do acknowledge that it's probably not necessary for a lot of people.

> I feel like a spec like this was meant for a pretty niche group of people.

That’s spot on actually.

Portability and human readability in a normal text editor are huge plusses for me.

I mostly use paper notebooks, but when I need to keep track of todos over a long period of time for a specific thing, I like to have a text file located with that thing. With all of these cloud-based tools we now use, everything’s refactored to be organized based on tool, then project instead of project, then tool. I for one am starting to rethink this. Changing of tools or people, or simply passage of time inevitably loses information, or knowledge of where information was stored.

I could see myself using this format for simple tracking in a git repo where I don’t want to use GitHub or another similar tool. One use case would be getting things done in a JIRA/middle-management heavy organization.

Having the spec is then nice because anyone could use their preferred tool if they want to and one could easily check for open todos in a bunch of folders/repos.

I appreciate the criticism, thanks! I disagree, though, that adhering to standardised formats is not worth it. Currently, there are countless todo apps and editor plugins out there, which all do very similar things. However, each needs their own dedicated editor plugin for syntax highlighting, and you can’t easily switch the client apps without having to also switch the underlying data format.

What I agree with is that standards limit the creative freedom of tool creators. But that’s the same balancing act all over again, no matter where you look at.

(comment deleted)
A spec makes it more easy to build tooling around it. I reckon the people that love emacs org-mode, do so not mainly because of its specification, but the power to manipulate those plain text files in the editor.
I think that having a formal spec would help since a lot of the minutiae that is done to format and the like can be in the form of snippets in (nearly all) text editors used today.

So just having the autocompletion for people editing in text does wonders.

As for standardization, applications don't have to target it as their on-disk format for it to be useful. Instead of bespoke JSON/XML schemas or proprietary formats, having a plain text export format is a big win. Specially if it's human readable and human writeable.

I'm not sure this is the best tool for an import-export format, as it is unable to capture all of the data available in some to do apps.

I could see it being OK as a sort-of data backup format. But it's missing a lot of data that really ought to be tracked by an app, like creation, update, and completion times for each item. Many apps also track priority, sort order, hidden/unhidden status, attachments, and other things. This stores none of that.

Even then, the value is fairly small. In 20+ years of using to do apps, I can think of very few times that I've referred back to completed to do items.

I disagree, having the spec is the first step to building tooling around it. People can port plugins that support this format to vim, eMacs, VSC, etc.. and create functionality around it. For example: reorder into a date view
I think the author is saying there is already a spec, just one abstraction layer above: Plain text. Anything that can read and write text can interact with the to-do list.

In some ways, it is more portable.

Still, why plain text? If the goal is “wrap it in UI” why a new white space, special characters.

Why not YAML or JSON and the vetted libraries to read and write the format?

As a user I don’t really have any concern with what underlying data format and structure it stores things in. I want to manage my todos!

This could be an SQLITE file for all I care.

Software engineering should be about more productive UX, not flexing one’s ability to parse arbitrary syntactic art.

I think the viewpoints on that are wildly diverse. As far as I’m concerned, it’s the exact opposite. Hence, I think it’s great that there is a big variety of different approaches that everyone can pick from according to their own preferences.
Sure; I’m just expressing mine. The “glyphs and how to display or sort them wars” aren’t important enough to me to take real offense to alternatives. This is just idle discourse for me.

Lindy Effect type thoughts, why import another dependency; familiarity, existing portability, and habits with current formats; deep and wide tooling and language support… road built; let’s drive to shovel poetic drivel out the door.

> Software engineering should be about more productive UX, not flexing one’s ability to parse arbitrary syntactic art.

Tasks lists are generally useless without their context. It makes sense to have tasks along their context (be it plain-text, markdown, JS, python...) Also it's more maintainable and portable. YAML/JSON/SQlite will be a headache when the user decide to migrate to another tool. This approach only require a text editor, any text editor in any platform. You can plug in whatever you prefer for syncing and sugar.

For a very few cases I use YAML to store data that isn't parsed by any program (only by me). And I can write a comment like 'TODO: Do something.' or "FIXME: X isn't working.' On the terminal using a code searcher and a text editor I can easily find and jump on those.

UX creates context from the users perspective, not the back end data format. This format creates a headache in that nothing can parse or write it except the humans that learn it.

I can easily search an SQLITE file from a CLI (wrote me a tool a long time ago to fuzzy find). I doubt the YAML lib for Python is going to become obsolete soon. I can instantly work with that format on any machine with a common language. There’s already Taskwarrior.

It’s electrons in a machine, hundreds of different paths to porting it around, changing it, etc.

Look, don’t get me wrong; I’m not about to pour sugar down someone’s gas tank. I’m just walking through my inner monologue debating this format someone chose to put up for open review and discussion.

I write data that makes sense to have as normalized in YAML format even if I'm not parsing it in any program because I may do so in the future and YAML is ergonomic.

But for things that shouldn't be normalized I write then as plain-text notes using markdown notation. It isn't true that nothing can parse plain text. I wrote a tool to do that and it works as expected. Of course it's bad design if you look exclusively from the software engineering perspective but ergonomics also matter and parsing text isn't hard.

Don't get me wrong also. I'm just a guy with peculiar use cases and bad experiences migrating away from Evernote and later Joplin.

I think it is nice when there is a well thought out spec for something. But in this particular case, I think it is not compatible enough with other tools.

In particular, Markdown has a todos (using the same `[ ]`) and just uses indentation for grouping. I find this more intuitive and it renders in markdown renderers.

For priorities, I have adopted the notation of OneNote which puts exclamation and Unicode star symbol next to the todo brackets.

I also use some other conventions:

[-] for obsolete rather than [~].

[>] for postponed until later

Implemented in my Todo manager TUI: https://github.com/coezbek/rodo

Might be right, but as an interchange format between todo-apps, might be worth it?
> In particular, Markdown has a todos (using the same `[ ]`) and just uses indentation for grouping.

Came here to mention the same thing. I use a plain text todo format that is quite similar (thought not nearly so thought out/complete) to the one OP is proposing, but I use indentation for grouping as it's a lot easier for me to visually identify related groups of tasks.

> A formal spec also doesn't help much for apps to use this format. There is not a huge need for portability between to do apps, and for most users to do items are ephemeral and not something that needs to be archived and revisited. Even if an app adopted this, being tied to a plain text format would likely hinder feature development, including the ability to sync across multiple devices. Beyond that, different to do apps use different systems of categorization and tagging, so really in practice I doubt this will become any kind of standardized format.

I disagree. I maintain a rather popular plain-text-based app [1] and the formal spec makes this something very very easy to add support for. Infact the only thing that could make this even easier is if there was a way to verify my own implementation.

[1] https://gitjournal.io

Yes, you could add support for it. To what end? Do you think the usage will be high enough to justify the effort to implement and maintain it?

Even imagining the ideal world where every to-do app implements this, portability of to-do items between apps just isn't that big of a problem. There isn't a big need to move long lists of to-do items between apps.

And in the real world, this won't be implemented perfectly. You'll have the App A implementation, the App B implementation, and so on. Look at Markdown. You'll have headaches migrating your to-do items automatically and in the end, most likely, you'll just end up copy and pasting them. It's not that hard and old to-do items aren't that important to the vast majority of people.

This sounds a bit defeatist.

Yes, it won't be perfect at first, but there is always a chance of reducing the barrier to entry. The lower it is, the more % of users / developers / apps are going to use it.

It's not defeatist. As I said, I just don't think, even in the optimal scenario, that it is a goal worth achieving. Personally I'd rather software developers focus their time on more worthwhile features.
What is worthwhile can vary widely. Like the quote that people use only a slice of Word, yet often different slices.
Not sure I agree. I didnt know about gitjournal until vHanda's post, but immediately saw how it could be a replacement for my use of Google Keep (which I use when I'm on the go vs at my laptop). And there was already an exporter for Google Keep. I'm guessing that exporter benefited from a spec being available.

Your point about "if you're the only one using it, just use it" does apply, but sometimes we do find ourselves being more successful than we originally expected and defining things via a spec is not a bad thing.

yes

To add to this, many markdown apps do support TODOs, but they use their own format. e.g. Bear uses

    - [ ] Unchecked
    - [X] Checked
If there was a widely-accepted standardized markdown format for TODOs you could write them in one app and then they would display properly in others.
Foam Notes also uses that same markdown format for checklists. I think that Markdown is a pretty good format for notes and is already used by enough apps.
Microsoft Azure DevOps does too.
I'm a happy gitjournal user, and I want to +1 this. I'm already using it for checklists as plain markdown, and the format is pretty similar. I can see a lot of value to this as a semi-markdown compatible extension or second app sharing the codebase.
Agree. Todo lists are ephemeral. They're not meant to be stored and archived. Just write the list already, execute the items in the list and move on. Focus on getting things done rather than creating new formats for these ephemeral lists.
> Todo lists are ephemeral. They're not meant to be stored and archived.

I have many recurring items on my todo list. So those might be nice to be portable between apps.

Agree, not everything needs a special format or spec. To me, it just obfuscates the core purpose of a to-do list for me, which is to record the bare essentials to remind me of things I need to do, then do them and forget about them. Anything else is just more overhead I don't need.
Where I think something like this is most useful is as a common interchange format. For example, if you are using TickTick as a todo app and decide you want to switch to using Notion or something. If there were an ecosystem of converters to this common format, that would make this trivial to do.
Kinda sorta related, on macOS, if you choose to store your Notes in a plain old e-mail server, they are stored as text files very similar to this.

Or at least they were last time I checked a few years ago. It was very handy to be able to access my Notes and lists from a regular old webmail interface.

I like it.

I do something similar for my todo file but organize by date. Most recent date first. Every day I review unchecked items from the previous day and move them to today or mark them obsolete.

It has the added functionality of serving as a nice log of my work.

So it looks something like this:

    2022-04-01
    ==========
    
    [ ] do a thing
    
    2022-03-31
    ==========
    
    [x] foo the baz
Me too, although I use markdown todo lists, starting with a minus.

I also record the creation date and timestamped notes on the progression of the task. And I use @ to keep tabs on tasks that I've delegated.

    2022-04-02
    - [x] [2022-03-30] do a thing #tag1 #tag2
        - 2022-03-31 10:30 notes about work being done thing
        - 2022-03-02 14:00 completed thing by using X
    - [ ] [2022-03-28] @delegated_person: do another thing
        - 2022-03-29 09:00 delegated_person reported that Y
I switched away from Workflowy to a plain text file format. Load times are quicker, navigation is quicker, can use keyboard only without a mouse, the UX can keep up with the pace of my thinking.

I prefer vimwiki for this purpose https://github.com/vimwiki/vimwiki

You can get plugins that sync it to a git repository. I love this.

There's also task warrior plugins, though I haven't figured out how that would for me, seems to get away from simple text files at that point.

Only thing I would think of changing would be allowing for the use of colons in tags to provide tag namespaces. Then it's fairly trivial to implement things like created on date, completion date, and the like since it's just "#created-on:yyyy-mm-dd" or "#completed-on:yyyy-mm-dd".

It also allows users more generic organization options, with filtering based on the namespaced tags being something trivial, but ultimately up to the user or the app that is interfacing with the xit file.

It's bullet journal notation meets plain-text format and I dig it.

I use pure text files for a lot of things, too, and I already use a similar system, but it's definitely more free-form.

Cool idea!

https://github.com/Vhyrro/neorg is a neovim format inspired by org-mode. It should be easier than learning the real org-mode. The real-org mode is not that hard to use though IMO.
Obsidian is pretty easy to use to maintain a to-do list as well.
Very cool! I made something very similar to this as a VS Code extension[1]. Inspired by the bullet journal method.

[1] https://marketplace.visualstudio.com/items?itemName=blt.blt

When I saw the OP's format, I immediately wanted a VS Code extension for it. This looks great, installing it as we speak.

In fact, I like your format slightly more, because when I complete tasks I usually just delete them -- no need for a checkbox.

This is really neat. It's similar to the BuJo rapid-logging-inspired system I handspun for myself around Markdown a few years ago that I outlined here:

https://news.ycombinator.com/item?id=21580133

I'd quit using that one since because too many Markdown editors have forgotten tabs are legal whitespace after a UL bullet, and that there are three different UL bullet characters (and it really doesn't help that the CommonMark examples page only docs `-` and `*`, even though `+` is part of the CommonMark spec too). In particular, without the tab support being implemented, there's no fixed gutter for the BuJo-style sigil and queries get much harder.

But I do miss the idea of those simple bullets. I may have to check out your extension.

What you didn't liked with todo.txt?
A few (cosmetic) details, for example:

- They don’t support multiline item descriptions. They actually prohibit that for a specific reason, because you can’t sort the lines lexicographically anymore. In my opinion, that should be an optional feature, however, which it is in [x]it!

- Creation and completion date are featured prominently, but I actually think they are not that important, and I’m not sure they are really worth some dedicated syntax. What I do find important, though, are due dates, and these are not natively supported in todo.txt

- I don’t like the notation of just preceding `x ` to the line for a checked item. It’s simple on the one hand, but it doesn’t look very tidy in the file.

I do something similar but I include informational notes as well (not just action items/todo's).

  * incomplete todo

  ~ completed todo

  - informational
Each day I create a new note, titled by date. Grep the folder for topics or incomplete action items. No tooling or overhead needed. I have never felt the need to syntax "ongoing" or "obsolete" items. It's either open or closed.
One other small thought I have is about the name. It's common to use "xit" in popular JavaScript test framework like Mocha and Jasmine to indicate an excluded test. Could cause some ambiguity or an unwanted association.
Looks like quite similar to my own document / task management grammar [1].

I wrote a small library to parse mine, and built many tools on top of it, including editor support, various CLIs for task management, calendar, activity tracking, content consumption, etc.

I invested a lot of time into learning Emacs, got into using Org, but Emacs is just too slow, and I got to a point where customizing the tool for what I want was harder than building a custom tool.

[1] https://i.imgur.com/Nm6e31W.png * sorry for ma english

Heh - just did the same thing over the last week to compile my task list into trello cards to share out =)