I used gitlab.com CI a lot but then at some point all the restrictions started and now it is not worth it trying to figure out how much quota is enough, especially for small personal projects. I don't remember the last time I wrote a git lab CI yaml file.
Make is still king in 2025.
I don't understand why someone would use Just or Taskfile instead of Make.
My only hypothesis is that people believe (erroneously) that whatever is new is automatically better than what is older.
I use Task and like it, though I have used make before and don't think it's awful.
Task's tracking of the source and the output feels cleaner than make's need for a clean command. I can have a tree of dependent tasks and it will rebuild the ones that are outdated without me doing a "make clean" and having to rebuild all of them.
The ability to include files is clean, though similar can be done in make with some recursion (which works, but I find hacky and hard to keep track of).
I also don't love make's DSL. I don't edit my build files often enough to really keep it in my head, so I feel like I'm constantly trying to remember how to do particular things.
Lastly, I think it's easier to share because even if you've never used Task the YAML is pretty self-descriptive. The first time I saw a Taskfile it wasn't hard to grok how it worked. Make is pretty opaque if you've never seen a Makefile before, and I've met a lot of junior devs that have never interacted with it.
To be fair, make is kind of weird in some ways that make it a pain to use if you're not used to it. Even just the stupid tab-only indentation is annoying. That said, it's ubiquitous and that wins over almost anything else in my opinion. Of course, you may take that with a grain of salt since I also write virtually all of my scripts in POSIX sh...
At the time I created it, I worked on Windows more often and I had a lot of trouble trying to find a Make build that works fine on Windows. The ones available for Windows are usually incompatible with the GNU version. So cross-platform support is one advantage of alternative tools.
Other than that, Task has a lot of features, so some use cases are not covered by Make.
That said, I'm not a Make hater. If it works for you, that's absolutely fine. Many people has found value in Task, though.
Congratulations on you project, hope to have once a project as succesfull as yours.
I would like to clarify that I don't mean to bash Task, just tired of critiques saying that Make is bad because is old, and Just and Task are better only because they are new.
The readme on Just repo explains pretty well why it's better than Make for the things people often misuse Make for, and why it's not intended for the use case that Make was originally built for.
I read Just's readme the other day.
Basically they say Just is better than Make because in Just all targets are phony by default (something you can make easily in Make). And because they provide a flag to list the targets (which you can make easily in Make).
And because Make is to too complex to differentiate between = and := (which as an user almost always gives you the same result, even if you don't understand the difference). These are basically the reasons, which are not convincing for me.
New = Better is indeed stupid but that's not whats happening here.
Make is a really powerful tool, with an expressive language that is quite esoteric with a bunch of idiosyncrasies (just like bash).
Most people are using Make as a task runner and it really falls short of the mark on this aspect. It can work, just like you can write a webserver in bash, but I think you'd be hard-pressed to find someone who would consider it to be a good idea.
Most people also conclude that "Well, Make is installed on everyones machine", but this also isn't true, it's an optional package and we often find ourselves installing it without much thought; making you believe that it was always included (I've done this plenty of times myself).
Make is not a task runner, it's a build system. You give it a bunch of files that need to be generated, and how to generate them; then you tell it which steps depend on which and voila! Make solves it for you.
How freaking cool is that?!! The price we pay is high (Yet another idiosyncratic language that we have to deal with), and that price is higher if we're not actually getting the value out of the freaking thing either.
I mean, wouldn't it be great if we had a Make that was more bash-compatible? That had easy discoverability of rules (maybe with a --list option to just targets?), that was more cross-platform and that supported parallel execution... Oh and golly, it would be lovely to have conditional logic - and since we're not using the build graph, or generating known artefacts, maybe we can remove those things and leave it up to our other build tools like Cargo, docker or Go?
Well, as it turns out, Just has those things, and operates this way. It's essentially what we keep using Make for; instead of using Make for what Make was actually made for.
<Make is a really powerful tool, with an expressive language that is quite esoteric with a bunch of idiosyncrasies (just like bash). > Agree
<"Well, Make is installed on everyones machine (....)"> It's not everywhere but almost.
<(Yet another idiosyncratic language that we have to deal with)> This is true. However, one has to choose its investments. I believe that Make is a powertool like awk, sed and bash, and despite its ideosyncracies, all of them have a positive ROI.
<Make is not a task runner, it's a build system.>
I think a lot of confusion comes from having the wrong perspective on what Make actually is. From the Oreilly book on Make:
"It is important to understand that make is sort of two languages in one. The first language describes dependency graphs consisting of targets
and prerequisites. The second language is a macro language for performing textual substitution. "
Make is a 1) language to express dependencies and a 2) language to template and do text substituion at a higher level than scripting languages; it's not a build system, though it's can be used as a tool to help compile C, C++ and possibly others langs. This gives you the ability to resolve simple or complex chains of dependencies by just specifying "target: prerequisities; recipe" and put variables everywhere to keep the code DRY and add conditional logic.
This means that Make shines in whatever follows the pattern "target: prerequisites; recipe" and that is almost all type of scripting! Including 'task runner' kind of jobs.
(In this sense, creating files out of files, and not recreating and existing file, is a "feature" but not the core of Make. )
Hence, when you say that it would be cool to be more bash-compatible I think Make provides a way (see the .ONESHELL target.)
The --list option, could be implemented with a really small awk script, and I also add some ASCII art.
Concerning the discoverability of rules, Make provides bash and zsh completion out of the box.
Parallel execution also works out of the box by adding the -J option.
Conditional logic could be added using "conditional processing directives" and with macro expansions.
Make indeed is really powerful, I would recommend everyone to checkout the Oreilly book on Make.
And again, I'm not trying to bash Just or Task. I'm trying to point out that only because a tool is new does not mean that is better than the old one.
Cool comparison. Both guys helped shape early computing but in totally different ways, one pushing from the garage, the other from within the system. It’s a good reminder that innovation doesn’t follow one path and impact isn’t always loud or obvious at first.
I know there's all kinds of biases in what we see.
But, from a european gamedev standpoint, I have never worked in a company that professionally depended on github-actions.
All I ever saw was Gitlab-CI and Jenkins (and a small instance of buildbot).
So seeing the absolute dominance of github-actions is somewhat jarring to me and doesn't paint a picture of my lived reality.
That said; none of what I'm talking about is open source - but I would expect to see more gitlab-ci in this list.
It seems biased that only GitHub was scraped, that seems like it would mostly exclude systems linked to other forges like GitLab CI.
I used gitlab.com CI a lot but then at some point all the restrictions started and now it is not worth it trying to figure out how much quota is enough, especially for small personal projects. I don't remember the last time I wrote a git lab CI yaml file.
Make is still king in 2025. I don't understand why someone would use Just or Taskfile instead of Make. My only hypothesis is that people believe (erroneously) that whatever is new is automatically better than what is older.
I use Task and like it, though I have used make before and don't think it's awful.
Task's tracking of the source and the output feels cleaner than make's need for a clean command. I can have a tree of dependent tasks and it will rebuild the ones that are outdated without me doing a "make clean" and having to rebuild all of them.
The ability to include files is clean, though similar can be done in make with some recursion (which works, but I find hacky and hard to keep track of).
I also don't love make's DSL. I don't edit my build files often enough to really keep it in my head, so I feel like I'm constantly trying to remember how to do particular things.
Lastly, I think it's easier to share because even if you've never used Task the YAML is pretty self-descriptive. The first time I saw a Taskfile it wasn't hard to grok how it worked. Make is pretty opaque if you've never seen a Makefile before, and I've met a lot of junior devs that have never interacted with it.
To be fair, make is kind of weird in some ways that make it a pain to use if you're not used to it. Even just the stupid tab-only indentation is annoying. That said, it's ubiquitous and that wins over almost anything else in my opinion. Of course, you may take that with a grain of salt since I also write virtually all of my scripts in POSIX sh...
I agree with you. Make has it's quirks, specially those builtin variables ($@, $<, etc), they are ugly but useful.
Task creator here.
At the time I created it, I worked on Windows more often and I had a lot of trouble trying to find a Make build that works fine on Windows. The ones available for Windows are usually incompatible with the GNU version. So cross-platform support is one advantage of alternative tools.
Other than that, Task has a lot of features, so some use cases are not covered by Make.
That said, I'm not a Make hater. If it works for you, that's absolutely fine. Many people has found value in Task, though.
Congratulations on you project, hope to have once a project as succesfull as yours. I would like to clarify that I don't mean to bash Task, just tired of critiques saying that Make is bad because is old, and Just and Task are better only because they are new.
The readme on Just repo explains pretty well why it's better than Make for the things people often misuse Make for, and why it's not intended for the use case that Make was originally built for.
I read Just's readme the other day. Basically they say Just is better than Make because in Just all targets are phony by default (something you can make easily in Make). And because they provide a flag to list the targets (which you can make easily in Make). And because Make is to too complex to differentiate between = and := (which as an user almost always gives you the same result, even if you don't understand the difference). These are basically the reasons, which are not convincing for me.
Anyway, 26K people find
New = Better is indeed stupid but that's not whats happening here.
Make is a really powerful tool, with an expressive language that is quite esoteric with a bunch of idiosyncrasies (just like bash).
Most people are using Make as a task runner and it really falls short of the mark on this aspect. It can work, just like you can write a webserver in bash, but I think you'd be hard-pressed to find someone who would consider it to be a good idea.
Most people also conclude that "Well, Make is installed on everyones machine", but this also isn't true, it's an optional package and we often find ourselves installing it without much thought; making you believe that it was always included (I've done this plenty of times myself).
Make is not a task runner, it's a build system. You give it a bunch of files that need to be generated, and how to generate them; then you tell it which steps depend on which and voila! Make solves it for you.
How freaking cool is that?!! The price we pay is high (Yet another idiosyncratic language that we have to deal with), and that price is higher if we're not actually getting the value out of the freaking thing either.
I mean, wouldn't it be great if we had a Make that was more bash-compatible? That had easy discoverability of rules (maybe with a --list option to just targets?), that was more cross-platform and that supported parallel execution... Oh and golly, it would be lovely to have conditional logic - and since we're not using the build graph, or generating known artefacts, maybe we can remove those things and leave it up to our other build tools like Cargo, docker or Go?
Well, as it turns out, Just has those things, and operates this way. It's essentially what we keep using Make for; instead of using Make for what Make was actually made for.
<Make is a really powerful tool, with an expressive language that is quite esoteric with a bunch of idiosyncrasies (just like bash). > Agree
<"Well, Make is installed on everyones machine (....)"> It's not everywhere but almost.
<(Yet another idiosyncratic language that we have to deal with)> This is true. However, one has to choose its investments. I believe that Make is a powertool like awk, sed and bash, and despite its ideosyncracies, all of them have a positive ROI.
<Make is not a task runner, it's a build system.> I think a lot of confusion comes from having the wrong perspective on what Make actually is. From the Oreilly book on Make:
"It is important to understand that make is sort of two languages in one. The first language describes dependency graphs consisting of targets and prerequisites. The second language is a macro language for performing textual substitution. "
Make is a 1) language to express dependencies and a 2) language to template and do text substituion at a higher level than scripting languages; it's not a build system, though it's can be used as a tool to help compile C, C++ and possibly others langs. This gives you the ability to resolve simple or complex chains of dependencies by just specifying "target: prerequisities; recipe" and put variables everywhere to keep the code DRY and add conditional logic.
This means that Make shines in whatever follows the pattern "target: prerequisites; recipe" and that is almost all type of scripting! Including 'task runner' kind of jobs.
(In this sense, creating files out of files, and not recreating and existing file, is a "feature" but not the core of Make. )
Hence, when you say that it would be cool to be more bash-compatible I think Make provides a way (see the .ONESHELL target.)
The --list option, could be implemented with a really small awk script, and I also add some ASCII art.
Concerning the discoverability of rules, Make provides bash and zsh completion out of the box.
Parallel execution also works out of the box by adding the -J option.
Conditional logic could be added using "conditional processing directives" and with macro expansions.
Make indeed is really powerful, I would recommend everyone to checkout the Oreilly book on Make.
And again, I'm not trying to bash Just or Task. I'm trying to point out that only because a tool is new does not mean that is better than the old one.
Cool comparison. Both guys helped shape early computing but in totally different ways, one pushing from the garage, the other from within the system. It’s a good reminder that innovation doesn’t follow one path and impact isn’t always loud or obvious at first.