devlog: user guide


Your work is more than a series of tasks (although, of course, you do have those). Sometimes the way forward is uncertain — you'll ask questions, prototype, clarify. As you do, you'll come to understand the problem deeply. You'll craft an elegant solution, maybe different from the one you thought initially. That's the challenge and the joy of building software. Devlog is a command-line tool designed for this kind of work.

It is not a project management tool, a bug tracker, a wiki, or a scrum board. Those are great when you need to coordinate, less so for your personal workflow. They add friction to every change, although change is inevitable. Rather than support your process, they constrain it.

Devlog is different. It gives you a space to prioritize tasks, pose questions, and realize solutions. It adapts to change, allowing you to effortlessly update tasks as your understanding evolves. And you can customize it to fit your workflow, not the other way around.

I hope you find it useful.


See the installation guide.


To create a new repository for your devlogs:

devlog init

By default, devlogs are stored in the directory at $HOME/devlogs. You can choose a different directory by setting the DEVLOG_REPO environment variable.

Examining the repository directory, you'll see a file called 000000001.devlog. This is your first devlog entry. It's just a text file.


To open the most recent devlog file:

devlog edit

The default editor is nano. You can choose a different editor by setting the DEVLOG_EDITOR environment variable. For example:

export DEVLOG_EDITOR=vim

Your first devlog entry has already been created. Open it, and you'll see something like:

Welcome to your devlog!

You can add tasks below using this format:
* Use an asterisk (*) for each task you want to complete today.
^ Use a caret symbol (^) for each task that's in progress.
+ Use a plus sign (+) for tasks you completed
- Use a minus sign (-) for tasks that are blocked.

As you work, you can write your questions, thoughts,
and discoveries alongside your tasks.  These will be
stored in your devlog so you can refer to them later.

As you can see, devlog provides a simple way to record tasks. Any line that starts with a *, ^, +, or - is a task. But your devlog is also a place for free-form thoughts. For example:

^ Add method `bar` to class `foo`
    The class is in `lib/`.
    The new method is a simple data transformation, so testing should be easy...
    I wonder if I can deprecate method `oldbar` once this is merged?

^ Update library `baz` to version 1.2.3
    Opened the PR, waiting on review.

+ Enable feature flag for cache optimization
    Done!  Checked the system this morning, performance is much better.

As you work, you may realize that some tasks are unnecessary, or maybe you need to add more. That's expected! Just make the changes and keep going.


Sometimes, you will want a quick overview of your tasks. "What was I working on before that meeting? What did I need code-reviewed?" To see your current tasks grouped by status:

devlog status

Other times, you will want to see your full devlog entries. "What was the name of that file with the LRU caching logic? What was the name of the branch that added the feature flag?" To see recent devlog entries:

devlog tail


Over time, your devlog will fill with old tasks and notes. This can be overwhelming. To stay focused on what's important now, you will occasionally run:

devlog rollover

This copies incomplete tasks to a new devlog file. You can do this at the end of the day, to prepare your work for the next day. Or, if you prefer, you can do it at the start of the next day, so you can review your notes from the day before.

Your previous devlog entry still exists! You can always view older entries using devlog tail.


shell scripts

Devlog is designed to be coupled like garden hose with other command-line tools. This allows you to customize it to your workflow.

For example, on many teams you will send a daily "standup" status report to a Slack channel. Suppose you want to report tasks you completed yesterday, tasks you are working on today, and blocked tasks. A simple shell script suffices:

#!/usr/bin/env sh
echo "Yesterday:"
devlog status -b 1 -s done  # completed in yesterday's entry
devlog status -s done       # completed in today's entry

echo "Today":
devlog status -s todo       # todo in today's entry

echo "Blocked:"
devlog status -s blocked    # blocked in today's entry

As another example, suppose you'd like the status report to automatically highlight tasks by status. If you are using vim and have installed the devlog syntax, then you can simply pipe the status output to vim:

devlog status | vim -R -c 'set filetype=devlog' -

That's a lot to type, so you probably want to define an alias in your .bashrc or .zshrc configuration:

alias dls="devlog status | vim -R -c 'set filetype=devlog' -"


Devlog can be extended through a mechanism called "hooks". A hook is an executable file located in the $DEVLOG_REPO/hooks directory. To enable a hook, make the file executable, like this:

chmod +x $DEVLOG_REPO/hooks/before-edit

The following hooks are available:

Hook Invoked By When Arguments
before-edit devlog edit Before opening the most recent devlog file in the editor. Absolute path of the devlog file.
after-edit devlog edit After the editor program exits with a successful status code. Absolute path of the devlog file.
before-rollover devlog rollover Before creating the new devlog file. Absolute path of the latest devlog file before rollover occurs.
after-rollover devlog rollover After creating the new devlog file. The first argument is the absolute path of the old devlog file; the second argument is the absolute path of the newly-created devlog file.

Hooks provide a flexible mechanism for integrating devlog with other command-line tools. For example, suppose you want to automatically commit your devlog entries to a git repository. One way to achieve this:

  1. Create an after-edit hook to stage the changes in git:
    #!/usr/bin/env sh
    set -e
    repo="$(dirname $(dirname $0))"
    git -C $repo add "$1"
  2. Create an after-rollover hook to commit and push the changes to a remote git repository:
    #!/usr/bin/env sh
    set -e
    repo="$(dirname $(dirname $0))"
    git -C $repo add $1
    git -C $repo add $2
    git -C $repo commit -m "Rollover to $(basename $2)"
    git -C $repo fetch
    git -C $repo rebase origin/master
    git -C $repo push
One can imagine other possible integrations, such as:

... or anything else that improves your productivity!


Devlog is available as a Rust library. Using the library, you can access and parse devlog entries. Please see the library documentation for details.