<!doctype html><html lang=en-ca data-theme=dark prefix="og: https://ogp.me/ns#"><head><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=color-scheme content="dark"><title>harsh - a minimalist CLI habit tracker | Daryl Manning</title><meta name=description content="Introducing harsh, a minimalist command line habit tracker to help you build or break habits (written in GoLang)."><meta name=keywords content="gtd,dev,oss,tools,go"><meta name=author content="Daryl Manning"><meta name=robots content="index, follow"><link rel=canonical href=https://daryl.wakatara.com/harsh-a-minimalist-cli-habit-tracker.md><meta property="og:type" content="article"><meta property="og:url" content="https://daryl.wakatara.com/harsh-a-minimalist-cli-habit-tracker.md"><meta property="og:title" content="harsh - a minimalist CLI habit tracker"><meta property="og:description" content="Introducing harsh, a minimalist command line habit tracker to help you build or break habits (written in GoLang)."><meta property="og:site_name" content="Daryl Manning"><meta name=twitter:card content="summary_large_image"><meta name=twitter:title content="harsh - a minimalist CLI habit tracker"><meta name=twitter:description content="Introducing harsh, a minimalist command line habit tracker to help you build or break habits (written in GoLang)."><meta property="article:published_time" content="2020-05-26T17:06:16+08:00"><meta property="article:modified_time" content="2026-04-14T17:07:11+08:00"><meta property="article:tag" content="gtd"><meta property="article:tag" content="dev"><meta property="article:tag" content="oss"><meta property="article:tag" content="tools"><meta property="article:tag" content="go"><link rel=stylesheet href=/scss/style.7edb6a978fd500189a3d31e468d6c7a61e1ef0a985373688127dd00fc8113256.css integrity="sha256-fttql4/VABiaPTHkaNbHph4e8KmFNzaIEn3QD8gRMlY="><link rel=preload href=/fonts/Geist-Variable.woff2 as=font type=font/woff2 crossorigin><link rel=preload href=/fonts/GeistMono-Variable.woff2 as=font type=font/woff2 crossorigin></head><body class=page-2020-05-26-harsh-a-minimalist-cli-habit-tracker><a href=#main-content class=skip-link>Skip to main content</a><header class=navbar role=banner><div class=container><div class=flex><div><a class=brand href=/ aria-label="Daryl Manning Home"><span class=brand-text>Daryl Manning</span></a></div><nav class="flex nav-links" role=navigation aria-label="Main navigation"><a href=/posts/>Blog</a>
<a href=/projects/>Projects</a>
<a href=/about/>About</a>
<button class=search-toggle type=button aria-label=Search title="Search (/)">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg></button></nav><button id=mobile-menu-button class=mobile-menu-button aria-label="Open navigation menu" aria-expanded=false aria-controls=mobile-menu-overlay>
<svg class="menu-icon" aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
<svg class="close-icon" aria-hidden="true" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button></div></div></header><div id=mobile-menu-overlay class=mobile-menu-overlay role=dialog aria-modal=true aria-label="Navigation menu" aria-hidden=true><nav class=mobile-menu-content role=navigation aria-label="Mobile navigation"><a href=/posts/>Blog</a>
<a href=/projects/>Projects</a>
<a href=/about/>About</a>
<button class="search-toggle mobile-search-toggle" type=button aria-label=Search>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
<span class=search-label>Search</span></button></nav></div><div class=search-overlay role=dialog aria-modal=true aria-labelledby=search-title><div class=search><h2 id=search-title class=sr-only>Search</h2><div class=search__input-wrapper><span class=search__icon aria-hidden=true><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
</span><input type=search class=search__input placeholder="Search articles..." autocomplete=off aria-label="Search query">
<span class=search__shortcut aria-hidden=true>/</span>
<button class=search__close type=button aria-label="Close search" title="Close (Esc)">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></button></div><div class=search__results role=listbox aria-label="Search results"></div><footer class=search__footer><nav class=search__hints aria-label="Keyboard shortcuts"><span class=search__hint><kbd>↑</kbd><kbd>↓</kbd> Navigate</span>
<span class=search__hint><kbd>↵</kbd> Select</span>
<span class=search__hint><kbd>esc</kbd> Close</span></nav></footer></div></div><main id=main-content role=main aria-label="Main content"><div class=container><article><header class=article-header><div class=thumb><div><h1>harsh - a minimalist CLI habit tracker</h1><div class=post-meta><div class=meta-line><time datetime=2020-05-26>May 26, 2020</time><span class=separator>·</span>
<span class=reading-time>4 min read</span></div><div class=article-taxonomies><div class=tags><a href=/tags/gtd/ class=tag>gtd</a>
<a href=/tags/dev/ class=tag>dev</a>
<a href=/tags/oss/ class=tag>oss</a>
<a href=/tags/tools/ class=tag>tools</a>
<a href=/tags/go/ class=tag>go</a></div></div></div></div></div></header></article><div class=article-post><p>I&rsquo;m happy to announce the open source release of harsh today.</p><p><a href=https://github.com/wakatara/harsh>Harsh is habit tracking for geeks</a>. A simple, minimalist CLI for tracking and understanding habits. Build great habits. Break bad ones.</p><p>Why? Habits, both good and bad, make us. We are what we do habitually. And what we do habitually ends up <a href=/systems-and-habits-for-focus-and-productivity/>being what we accomplish</a>.</p><p>You can grab harsh most easily via <a href=https://brew.sh/>homebrew</a> on OSX or linux with a simple:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1
</span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>λ ~ brew install wakatara/tap/harsh
</span></span></code></pre></td></tr></table></div></div><p>or on Linux via <a href=https://snapcraft.io/>snap</a> with:</p><div class=highlight><div class=chroma><table class=lntable><tr><td class=lntd><pre tabindex=0 class=chroma><code><span class=lnt>1
</span></code></pre></td><td class=lntd><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl>λ ~ sudo snap install harsh
</span></span></code></pre></td></tr></table></div></div><p>Otherwise, <a href=https://github.com/wakatara/harsh/releases>binaries are available in your OS and architecture of choice</a>.</p><p>And you can <a href=https://github.com/wakatara/harsh>find the source here</a> if you prefer compiling your own binaries.</p><h2 id=why-a-cli-tracker>Why a CLI tracker?</h2><p>A big revelation for me when I started tracking habits was how inconsistent I <em>actually</em> was despite how my brain tricked me into thinking I wasn&rsquo;t. Tracking ends up being important. So, I started testing habit trackers. Mobile were good for recording on the fly, but gave no insights into patterns and were ultimately demotivating. Emacs&rsquo; org-habits mode was overly complex and finicky.</p><p>Relief came with a Rust-based CLI in <a href=https://github.com/blinry/habitctl>habitctl</a> about 16 months back. Simple. One file for habits tracked, one for logging, and importantly, long-arc consistency graphs (aka Seinfeld graphs) to show long term trends and problems at a glance, and to act as motivation to keep chains going. Despite submitted PRs for fixes and features to the app though, it seems to be abandonware.</p><p>So, I decided to take the core ideas and build on them, cause&mldr; open source. I also built the new app in Go as I felt it reduced the friction in using (and developing) harsh as a full Rust environment was needed to compile and use habitctl (though Rust <em>is</em> cool).</p><p><a href=https://github.com/wakatara/harsh>harsh is the result</a> (harsh taskmaster, actually). It&rsquo;s goals: simplicity, visibility, and your consistency. I&rsquo;ve fixed core habitctl features and added support for skips, warnings (when you are about to break the chain), proper score calculation, and corrected sparklines graphing. I&rsquo;ll be adding in comment logging and parsing shortly and have an idea about how to measure changes in habit periodicity over time (eg. you move a habit 2 days to once a week once it&rsquo;s ingrained). Binaries available across major platforms to reduce barriers to adoption, and make install simple.</p><h2 id=so-how-does-it-work>So, how does it work?</h2><p>How do you use it? My harsh setup has <code>~/.config/harsh</code> directory symlinked to Dropbox so files get versioned and backed up (please feel free to write a git hook if you want one), and I have a dedicated tmux pane in iTerm2 so I have the 100 day consistency graph view given by <code>harsh log</code> and <code>harsh todo</code> up virtually all the time. It keeps me motivated and ensures visibility with multiple glances a day when switching to do command line tasks.</p><p>I&rsquo;ve shell aliased <code>h</code> to the <code>harsh</code> command so it&rsquo;s even quicker with <code>h log</code> (<code>h l</code>), <code>h todo</code> (<code>h t</code>), and <code>h ask</code> (<code>h a</code>). I use one log and habit file for each year and create new ones and archive the old Jan 1 (or did this year anyway).</p><p>When I make boo-boos I can trivially edit the log file via emacs/vim/VSCode and I keep a running commented version of the habits file to explain why X went well or poorly for a habit tracked on any given day (right now, you can put in comments manually in the file and they will still parse tho I&rsquo;d like to do that on the fly when recording.). The text file&rsquo;s format is parsable with standard text tools for data science analysis or spreadsheet for more advanced analysis than 100 days. It&rsquo;s a CLI app so it&rsquo;s targeted at engineers and data scientists.</p><p>PRs and feature requests welcome though I am trying to keep the app as simple, performant, and lightweight as possible. The <a href=https://github.com/wakatara/harsh>code is here on Github</a> and released under an MIT license. Please discuss issues, bugs, or features in the Github issue tracker. After this initial release I&rsquo;ll be refactoring the code from some great reviews I got on the initial code base as well as adding in a pair of features and testing an idea about how to track changes to the periodicity of habits over time (habits changing over time will surprise you.)</p><p>My hope is that it unambiguously improves your life and helps you, much as it did me, developing good (or breaking bad) habits. If you <em>are</em> finding it useful, lemme know by mention on <a href=https://mastodon.social/@awws>@awws on mastodon</a> or <a href=mailto:hola@wakatara.com>via mail from the blog</a>. Would love to hear back on how you&rsquo;re using it, if it&rsquo;s helped, and how it might improve.</p></div></div><div class=container><nav class="flex container suggested" aria-label="Post navigation"><a rel=prev href=/productivity-buckets-reviews-and-visibility/ title="Previous post (older)"><span>← Previous</span>
<strong>Productivity buckets, reviews, and visibility</strong>
</a><a rel=next href=/organizing-effective-data-teams/ title="Next post (newer)"><span>Next →</span>
<strong>Organizing Effective Data Teams</strong></a></nav></div></main><footer class=footer role=contentinfo><div class=container><div class=footer__inner><div class=footer__copyright><a href=https://creativecommons.org/licenses/by-nc/4.0/ target=_blank rel=noopener aria-label="Creative Commons BY-NC 4.0 License" class=footer__cc><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M10 9.3a2.8 2.8.0 00-3.5 1.9 2.8 2.8.0 001.9 3.5 2.8 2.8.0 003.5-1.9"/><path d="M17 9.3a2.8 2.8.0 00-3.5 1.9 2.8 2.8.0 001.9 3.5 2.8 2.8.0 003.5-1.9"/></svg>
</a><span>2004–2026 · Daryl Manning</span></div><div class=footer__social><a href=https://github.com/wakatara target=_blank rel=noopener aria-label=github><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37.0 00-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44.0 0020 4.77 5.07 5.07.0 0019.91 1S18.73.65 16 2.48a13.38 13.38.0 00-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07.0 005 4.77 5.44 5.44.0 003.5 8.55c0 5.42 3.3 6.61 6.44 7A3.37 3.37.0 009 18.13V22"/></svg></a>
<a href=https://www.linkedin.com/in/daryl-manning/ target=_blank rel=noopener aria-label=linkedin><svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853.0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601.0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062.0 110-4.124 2.062 2.062.0 010 4.124zM7.119 20.452H3.555V9h3.564v11.452z"/></svg></a>
<a href=https://mastodon.social/@awws target=_blank rel="noopener me" aria-label=mastodon><svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor"><path d="M23.193 7.879c0-5.206-3.411-6.732-3.411-6.732C18.062.357 15.108.025 12.041.0h-.076c-3.068.025-6.02.357-7.74 1.147.0.0-3.412 1.526-3.412 6.732.0 1.192-.023 2.618.015 4.129.124 5.092.934 10.109 5.641 11.355 2.17.574 4.034.695 5.535.612 2.722-.151 4.25-.972 4.25-.972l-.09-1.975s-1.945.613-4.13.539c-2.165-.074-4.449-.232-4.799-2.892a5.39 5.39.0 01-.048-.745s2.125.52 4.82.643c1.648.075 3.196-.097 4.769-.283 3.014-.36 5.638-2.218 5.968-3.916.52-2.673.477-6.524.477-6.524zm-4.024 6.71h-2.497V8.469c0-1.29-.541-1.944-1.625-1.944-1.198.0-1.798.776-1.798 2.31v3.346h-2.482V8.834c0-1.534-.6-2.31-1.798-2.31-1.084.0-1.625.655-1.625 1.945v6.119H4.847V8.286c0-1.289.328-2.313.987-3.07.68-.758 1.569-1.146 2.674-1.146 1.278.0 2.246.491 2.886 1.474L12 6.585l.605-1.04c.64-.984 1.608-1.475 2.886-1.475 1.104.0 1.994.388 2.674 1.145.659.758.986 1.782.986 3.07v6.304z"/></svg></a>
<a href=mailto:hola@wakatara.com target=_blank rel=noopener aria-label=email><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94.0 01-2.06.0L2 7"/></svg></a>
<a href=/index.xml target=_blank rel=noopener aria-label=rss><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11a9 9 0 019 9"/><path d="M4 4a16 16 0 0116 16"/><circle cx="5" cy="19" r="1"/></svg></a></div></div></div></footer><button class="fab scroll-to-top" aria-label="Scroll to top" title="Scroll to top">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m18 15-6-6-6 6"/></svg>
</button>
<script src=/js/anchors.6b032aa12665340e2fab00cce8f77954dac968c1fb1896263e477df64ebd939f.js integrity="sha256-awMqoSZlNA4vqwDM6Pd5VNrJaMH7GJYmPkd99k69k58="></script><script src=/js/scroll-to-top.55fd8003a1b31e1e1a3416423c60234b0fef9f1a4dded829f6b0a26aa2369836.js integrity="sha256-Vf2AA6GzHh4aNBZCPGAjSw/vnxpN3tgp9rCiaqI2mDY="></script><script src=/js/search.f72a184f7af354c799a8f62a7d8e43af4ec7a2d05f7fde5fd8eac0bc52ca3ab9.js integrity="sha256-9yoYT3rzVMeZqPYqfY5Dr07HotBff95f2OrAvFLKOrk="></script><script src=/js/menu.46214a24eaa73e4609fd4697aeef7307fd30c13e502469df5af17762a94881be.js integrity="sha256-RiFKJOqnPkYJ/UaXru9zB/0wwT5QJGnfWvF3YqlIgb4="></script></body></html>