TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Show HN: Makedown – A Markdown powered Makefile alternative

142 pointsby timz7 months ago
`makedown` allows you to organise your shell scripts in one or several markdown files, by mix and matching different scripting languages for various commands and needs.<p>zsh&#x2F;bash&#x2F;sh, python, javascript or anything else available on your system.<p>Handy for replacing one-line-based package.json scripts or shell-based Makefiles.<p>One can also write documentation and explanations to various commands in the same `.md` file.<p>Most editors highlight correctly most languages in the markdown code blocks, even when you use several scripting languages.<p>Here is a demo .md file <a href="https:&#x2F;&#x2F;github.com&#x2F;tzador&#x2F;makedown&#x2F;blob&#x2F;main&#x2F;DEMO.md">https:&#x2F;&#x2F;github.com&#x2F;tzador&#x2F;makedown&#x2F;blob&#x2F;main&#x2F;DEMO.md</a><p>More information available in the <a href="https:&#x2F;&#x2F;github.com&#x2F;tzador&#x2F;makedown&#x2F;blob&#x2F;main&#x2F;README.md">https:&#x2F;&#x2F;github.com&#x2F;tzador&#x2F;makedown&#x2F;blob&#x2F;main&#x2F;README.md</a><p>Provided the following `example.md` in the root of your project, the defined commands are available to run from any of the projects subfolders:<p><pre><code> --- Start of example.md --- # hello Prints &quot;Hello&quot; to `stdout` using Zsh. ```zsh echo &quot;Hello&quot; ``` # world Just prints &quot;World&quot; to `stdout` using JavaScript. ```js console.log(&quot;World&quot;); ``` # weather-tomorrow Prints the weather for tomorrow to `stdout` using Zsh. ```zsh curl wttr.in&#x2F;tomorrow ``` # generate-password Prints a random password to `stdout` using Python. ```python import random import string length = 16 characters = string.ascii_letters + string.digits + string.punctuation password = &#x27;&#x27;.join(random.choice(characters) for _ in range(length)) print(password) ``` --- End of example.md --- </code></pre> You can run any of the commands from anywhere in the project, just by typing `makedown a-command-name` or a shorter `m a-command-name`.<p><pre><code> $ makedown --help hello - Prints &quot;Hello&quot; to `stdout` using Zsh. world - Just prints &quot;World&quot; to `stdout` using JavaScript. weather-tomorrow - Prints the weather for tomorrow to `stdout` using Zsh. generate-password - Prints a random password to `stdout` using Python. $ makedown hello Hello $ makedown world World $ m weather-tomorrow Sunshine # prints more details actually $ m generate-password 4444444444444444 $ m generate-password --help Prints a random password to `stdout` using Python. </code></pre> The commands have simple syntax, they start with a header with a link and stop when the next header starts.<p>Like so:<p><pre><code> # [a-command-name]() A short description. Some documentation. ```bash some command ``` </code></pre> You can use other interpreters, like `python`, `node`, `ruby`, etc.<p>You can also use a custom interpreter specified using hashbang, like:<p><pre><code> # [run-deno-script]() Runs a script using the Deno interpreter. Deno has to be installed on your system. ```typescript #!&#x2F;usr&#x2F;bin&#x2F;env deno run const message: string = &quot;hello, world&quot;; console.log(message); ``` </code></pre> All the .md files in the current directory and all the parents are examined when looking for commands.<p>Would be very grateful for any suggestions or other feedback.<p>Thank you.

30 comments

fodkodrasz7 months ago
Does it support dependency handling between targets, and efficient partial remake of only the changed subtree of the dependency graph? Because what many people miss about make is the support for this, and think it is a way to make &quot;commands&quot; for single level recipies, and auto-complete their names in the shell. A simple shell script would be a trivial solution for that already.<p>Make does:<p>- topological sorting based ordering of the dependency tree<p>- skipping of already up to date targets<p>- supports parallel execution of independent dependency subtrees<p>The webpage is totally unclear on this, and to me it looks like it only allows for a named entrypoint to some script snippets.<p>I&#x27;m a literal programming fan though, and this is a nice start, but i recommend clarifying the docs on this.
评论 #41858224 未加载
评论 #41871313 未加载
djbusby7 months ago
X is kinda overloaded. Maybe &quot;makedown&quot;? Or something?<p>I just do mine in bash (make.sh) and it runs scripts from make.d&#x2F; which are in whatever (python, js bash, PHP)
评论 #41851236 未加载
divbzero7 months ago
This is pretty cool.<p>For one of my projects, I tried something similar where I had code blocks in <i>README.md</i> like:<p><pre><code> Usage ----- `pip install bar` and import `foo`: ```python import foo from bar ``` Run `foo.alice` with default arguments: ```python foo.alice() ``` Run `foo.bob` while specifying `baz`: ```python foo.bob(baz=0) ``` </code></pre> And a <i>Makefile</i> like:<p><pre><code> .PHONY: demo demo: venv @. .venv&#x2F;bin&#x2F;activate; sed -n &#x27;&#x2F;^```python&#x2F;,&#x2F;^```&#x2F;p&#x27; &lt; README.md | sed &#x27;&#x2F;^```&#x2F;d&#x27; | python .PHONY: venv venv: .venv&#x2F;bin&#x2F;activate requirements.txt @. .venv&#x2F;bin&#x2F;activate; pip install -qU pip @. .venv&#x2F;bin&#x2F;activate; pip install -qUr requirements.txt .venv&#x2F;bin&#x2F;activate: @python3 -m venv .venv </code></pre> So you could run all those <i>README.md</i> code blocks with:<p><pre><code> make demo</code></pre>
评论 #41858668 未加载
snake_case7 months ago
It’s great to see more tools taking advantage of the markdown syntax.<p>I’m the creator of Mask[0], a very similar tool built with Rust. I was originally inspired by Maid[1], which is an older take on this idea built with Node and no longer maintained I believe.<p>I see this is based on Node as well, and I appreciate that it currently has zero dependencies. Nice work!<p>[0]: <a href="https:&#x2F;&#x2F;github.com&#x2F;jacobdeichert&#x2F;mask">https:&#x2F;&#x2F;github.com&#x2F;jacobdeichert&#x2F;mask</a><p>[1]: <a href="https:&#x2F;&#x2F;github.com&#x2F;egoist&#x2F;maid">https:&#x2F;&#x2F;github.com&#x2F;egoist&#x2F;maid</a>
评论 #41856471 未加载
tonnydourado7 months ago
That&#x27;s nice, but a tool like this *HAS* to be distributed as a single binary, otherwise it&#x27;s just too much hassle to bootstrap it, specially on Windows, or stripped out docker containers.
评论 #41858631 未加载
porridgeraisin7 months ago
It&#x27;ll be nice if you could make it level 2 headers. Reason: if we want to make it html to display as a webpage, we won&#x27;t end up with multiple H1s, and we can have a H1 for like the name of the app or something.
评论 #41828411 未加载
timz7 months ago
- renamed to `makedown` - rewrote in python, since it is available out of the box on most POSIX and in GitHub actions - Updated to `### [my-command]() Explanation of command` syntax, this way GitHub highlights the commands nicely<p>Thank you for all the feedback
psibi7 months ago
This is an interesting approach. These days I have completely switched to just[0] tool for similar use case.<p>[0]: <a href="https:&#x2F;&#x2F;github.com&#x2F;casey&#x2F;just">https:&#x2F;&#x2F;github.com&#x2F;casey&#x2F;just</a>
kitd7 months ago
Looks nice!<p>I used XC for a bit, which does a similar thing, but have since reverted to make. The self-documenting nature of these tools can be very useful.<p><a href="https:&#x2F;&#x2F;xcfile.dev&#x2F;" rel="nofollow">https:&#x2F;&#x2F;xcfile.dev&#x2F;</a>
rpastuszak7 months ago
Aaages ago a I built a little tool to provide a TUI for NPM scripts (<a href="https:&#x2F;&#x2F;www.npmjs.com&#x2F;package&#x2F;lana-cli" rel="nofollow">https:&#x2F;&#x2F;www.npmjs.com&#x2F;package&#x2F;lana-cli</a>)<p>If you have a README with a list of build tasks, it&#x27;ll pull its content and give nicer names to whatever is placed in package.json scripts field.<p>(I&#x27;m using comments for that which feels clunky)<p>I don&#x27;t update it often, but I still use it almost every day.
quantadev7 months ago
The growing popularity of Jupyter Notebooks has made people realize the power and convenience of mixing executable script&#x2F;code with documentation, in the inverted way from normal. Normally we have code with embedded docs&#x2F;comments, but in this new approach we have documents with embedded code. Opposite way around. I like where all this is going, but I have a question:<p>Maybe we can make the embedded code be &quot;format independent&quot; or have different embedding syntax to extract the code from various forms of docs? Technically Markdown is already a special case of plain ASCII text, so that&#x27;s cool. But since Emacs Org Mode (which is supported even in VSCode via a plugin) we could have a way that&#x27;s compatible with Org Mode as well? Or would that be replicating existing Org Mode features too much? I&#x27;m not experienced in Org Mode other than to prove that VSCode plugin works however, so that&#x27;s why I have to ask.
评论 #41865166 未加载
perpil7 months ago
I do something like this with <a href="https:&#x2F;&#x2F;speedrun.cc" rel="nofollow">https:&#x2F;&#x2F;speedrun.cc</a> except it runs in the browser on top of your markdown in GitHub. This lets you prompt for inputs and run JavaScript and use a toolbar to context switch. For command lines it copies the command to the clipboard so you can run it.
Riverheart7 months ago
Really like the simplicity of the project (this is a compliment, the root is not overwhelming with files). Nice that this tool uses only system libraries. Way easier to distribute a single file with leverages already installed languages.<p>Thanks for sharing!
qazxcvbnm7 months ago
For myself, I just make a directory `workflows` and put all my scripts in it, and organise related scripts into subdirectories, so that I can use tree and filesystem tools to check what subcommands are available.
timz7 months ago
Thinking about the suggestion regarding command dependencies, possibly we could add something similar to Makefile:<p><pre><code> ## [clean]() Cleans the generated files ```bash rm -rf .&#x2F;build ``` ## [init]() Initializes the build folder ```bash mkdir -p .&#x2F;build ``` ## [build](clean, init) Builds the project This command depends on clean, and init, which are executed in that order beforehand. gcc magic.c -o .&#x2F;build&#x2F;magic</code></pre>
评论 #41865186 未加载
philsnow7 months ago
This reminds me a bit of org-babel’s support for running blocks in any language.<p>I like the idea and the execution. This bit though:<p>&gt; makedown.sh<p>&gt; npm install -g ...<p>&gt; #!&#x2F;usr&#x2F;bin&#x2F;env python<p>Gives me a bit of whiplash. I get wanting to use npm to install, since 1) lots of people have it installed and 2) it’s reasonably cross-platform and it seems like makedown is as well.<p>I don’t see a reason for it to be named makedown.sh instead of just makedown, though. Make itself doesn’t depend on sh to my knowledge, and you could have a makedown file with no shell build rules at all.
评论 #41855611 未加载
bryanhogan7 months ago
This is actually quite neat! Thank you for building this.<p>Agree with the idea already stated here to use &lt;h2&gt; elements instead of &lt;h1&gt;.
az09mugen7 months ago
That&#x27;s an interesting idea you had, it makes me think of a mix between a jupyter notebook and a makefile, sort of, based on md files. I like the concept, but I need to test it to see if it fits my needs. Just a question about python and zsh, do they need to be pre-installed in your OS and accessible from PATH, that&#x27;s it ?
评论 #41828247 未加载
anthk7 months ago
Instead of &quot;People spent years trying to reimplement Unix, poorly&quot;, the new (older actually, as ITS&#x2F;Emacs predate Unix) motto should be &quot;People still spents decades reimplementing Emacs, poorly&quot;. Now, with Org-Mode :)
zahlman7 months ago
&gt;One can type `--help` after `x my-command` to print out the help associated with that command.<p>I assume that there is no support for the scripts having their own command-line arguments? Or how do you disambiguate?<p>Anyway, this seems like an interesting demo, but it&#x27;s hard to imagine the use case.
评论 #41828409 未加载
timz7 months ago
Currently implementation is in python, since it is available in many places, but not all.<p>What would be pros and cons of implementing it in:<p><pre><code> - bash&#x2F;zsh - keep in python - rust&#x2F;go</code></pre>
timz7 months ago
published 0.3 version pnpm install -g @tzador&#x2F;x.md<p>- better --help messages with or without command - ## level 2 headers are used - the temp file is created in current folder, like that importing npm modules from current project works
dsp_person7 months ago
Some ideas:<p>- can capture output and be updated &amp; displayed in the markdown doc.<p>- persistent kernels
评论 #41874528 未加载
nunobrito7 months ago
Plus points for being a readable format that can be displayed great on HTML or PDF.<p>At the same time easy to edit and easy to enhance with different build languages as needed.
exabrial7 months ago
What you seek is a schema, and an exterior that can read, content assist, and validate inline after each word is typed.
emareg7 months ago
Nice idea! Can I reuse variables that I have defined in e.g. a JS code block in another ZSH code block and vice versa?
评论 #41874532 未加载
pjc507 months ago
This feels strictly worse than just keeping them in separate files with comments?
cxr7 months ago
Just change your README to README.html, and put your build script there.
mutant7 months ago
404
评论 #41825957 未加载
donq1xote17 months ago
Hey dude: This is project looks promising. I would like to check out.