<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Green Threads</title>
    <description>The latest articles on DEV Community by Green Threads (@green_threads).</description>
    <link>https://dev.to/green_threads</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4084185%2Fff39a112-5dd7-4798-b8f5-02a1d0f9e1e1.png</url>
      <title>DEV Community: Green Threads</title>
      <link>https://dev.to/green_threads</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/green_threads"/>
    <language>en</language>
    <item>
      <title>I got annoyed at just enough times that I wrote my own version</title>
      <dc:creator>Green Threads</dc:creator>
      <pubDate>Mon, 24 Aug 2026 16:35:39 +0000</pubDate>
      <link>https://dev.to/green_threads/i-got-annoyed-at-just-enough-times-that-i-wrote-my-own-version-2ie1</link>
      <guid>https://dev.to/green_threads/i-got-annoyed-at-just-enough-times-that-i-wrote-my-own-version-2ie1</guid>
      <description>&lt;p&gt;I use &lt;code&gt;just&lt;/code&gt; on basically every project I touch. It's good. But there were a few things about it that annoyed me often enough that I ended up writing my own runner instead of just living with it, which is how you end up with yet another CLI tool nobody asked for. Anyway, here it is: &lt;strong&gt;ndo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Three things specifically:&lt;/p&gt;

&lt;p&gt;Every time I wanted a one-line shortcut added, I had to go open the justfile, find where to put it, type it out, save, switch back. For a two-second alias that's way more steps than it should be. &lt;br&gt;
So &lt;code&gt;ndo add&lt;/code&gt; is a real command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ndo add deploy &lt;span class="s2"&gt;"./scripts/deploy.sh {{env}}"&lt;/span&gt; &lt;span class="nt"&gt;--param&lt;/span&gt; &lt;span class="nb"&gt;env&lt;/span&gt; &lt;span class="nt"&gt;--local&lt;/span&gt; &lt;span class="nt"&gt;--desc&lt;/span&gt; &lt;span class="s2"&gt;"Deploy to the given environment"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No editor round trip. Leave off &lt;code&gt;--local&lt;/code&gt; and it goes into a central file instead (&lt;code&gt;~/.ndo/central.toml&lt;/code&gt;) that's shared across every project on the machine, so stuff like &lt;code&gt;open&lt;/code&gt; or a couple git shortcuts don't have to be re-declared per repo. &lt;code&gt;just&lt;/code&gt; doesn't really give you a clean way to split "recipes I want everywhere" from "recipes for this one project" - it's one file. ndo just has both, and if a recipe exists in both, local wins, no warning printed. That's on purpose, not an oversight - I don't want a tool nagging me every single run about something that's expected 99% of the time. It's written down in the docs once instead.&lt;/p&gt;

&lt;p&gt;The other thing: passing arguments. I wanted &lt;code&gt;ndo open ./file.txt&lt;/code&gt; to just bind &lt;code&gt;./file.txt&lt;/code&gt; to the recipe's parameter without extra syntax at the call site. That part works now, which honestly is most of why I use this over &lt;code&gt;just&lt;/code&gt; day to day.&lt;/p&gt;

&lt;p&gt;There's also a lookup-table thing (&lt;code&gt;ndo var&lt;/code&gt;) that I added mostly for myself, for aliasing folder paths I open constantly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ndo add o &lt;span class="s2"&gt;"code {{folder}}"&lt;/span&gt; &lt;span class="nt"&gt;--param&lt;/span&gt; folder &lt;span class="nt"&gt;--local&lt;/span&gt;
ndo var add folder work &lt;span class="s2"&gt;"C:&lt;/span&gt;&lt;span class="se"&gt;\U&lt;/span&gt;&lt;span class="s2"&gt;sers&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="s2"&gt;ev&lt;/span&gt;&lt;span class="se"&gt;\p&lt;/span&gt;&lt;span class="s2"&gt;rojects"&lt;/span&gt; &lt;span class="nt"&gt;--local&lt;/span&gt;

ndo o work            &lt;span class="c"&gt;# -&amp;gt; code C:\Users\dev\projects&lt;/span&gt;
ndo o D:&lt;span class="se"&gt;\s&lt;/span&gt;ome&lt;span class="se"&gt;\o&lt;/span&gt;ther&lt;span class="se"&gt;\p&lt;/span&gt;ath   &lt;span class="c"&gt;# no match, so it's used as-is&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and recipe dependencies, if you need one recipe to run others first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ndo add deploy &lt;span class="s2"&gt;"./scripts/deploy.sh {{env}}"&lt;/span&gt; &lt;span class="nt"&gt;--param&lt;/span&gt; &lt;span class="nb"&gt;env&lt;/span&gt; &lt;span class="nt"&gt;--depends&lt;/span&gt; build &lt;span class="nt"&gt;--depends&lt;/span&gt; lint &lt;span class="nt"&gt;--local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;build&lt;/code&gt; and &lt;code&gt;lint&lt;/code&gt; run first in order, and if two recipes both depend on the same thing it only runs once across the whole chain.&lt;/p&gt;

&lt;p&gt;Quickstart if you want to poke at it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ndo init
ndo add open &lt;span class="s2"&gt;"code {{file}}"&lt;/span&gt; &lt;span class="nt"&gt;--param&lt;/span&gt; file &lt;span class="nt"&gt;--local&lt;/span&gt;
ndo open ./main.go
ndo list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Single static binary, Linux/macOS/Windows, amd64/arm64. TOML config, no YAML anywhere (recipes are shell strings full of &lt;code&gt;:&lt;/code&gt; and &lt;code&gt;{{}}&lt;/code&gt; — YAML's implicit typing makes that miserable, TOML doesn't have that problem).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;green-threads/ndo/ndo
&lt;span class="c"&gt;# or on Windows&lt;/span&gt;
scoop bucket add ndo https://github.com/green-threads/scoop-ndo
scoop &lt;span class="nb"&gt;install &lt;/span&gt;ndo
&lt;span class="c"&gt;# or&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/green-threads/ndo/main/install/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;v1.1.0 is current, just added colored output for &lt;code&gt;list&lt;/code&gt;/&lt;code&gt;var list&lt;/code&gt;/errors. It's still small on purpose — no &lt;code&gt;--parallel&lt;/code&gt;, no remote imports, nothing fancy yet. I'd rather the core three things above stay solid than bolt on features nobody's asked for.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/green-threads/ndo" rel="noopener noreferrer"&gt;https://github.com/green-threads/ndo&lt;/a&gt;&lt;br&gt;
Docs: &lt;a href="https://ndo.greenthreads.dev" rel="noopener noreferrer"&gt;https://ndo.greenthreads.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If anyone's hit the same friction with &lt;code&gt;just&lt;/code&gt; (or has reasons the silent override thing is a bad idea) I'd genuinely like to hear it in the comments.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>productivity</category>
      <category>tools</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
