[HN Gopher] Mill: A better build tool for Java, Scala, and Kotlin
       ___________________________________________________________________
        
       Mill: A better build tool for Java, Scala, and Kotlin
        
       Author : lihaoyi
       Score  : 72 points
       Date   : 2025-07-16 15:45 UTC (7 hours ago)
        
 (HTM) web link (mill-build.org)
 (TXT) w3m dump (mill-build.org)
        
       | ivolimmen wrote:
       | It's nice that there are options but i'm sticking with maven. I
       | hate programming my build; maven is just a configuration file.
        
         | jpitz wrote:
         | Which works fine.....until it doesn't. Many non-trivial builds
         | require custom logic, and trying to do that in maven was
         | painful the last time I tried it.
        
           | throwaway7783 wrote:
           | Out of curiosity, what is non-trivial in this context?
        
           | spullara wrote:
           | I have found that if it is hard to do in maven you probably
           | shouldn't be doing it or there is a better way.
        
           | ackfoobar wrote:
           | Yeah. It's Greenspun's tenth rule.
           | 
           | If you have any complexity, programming against a good
           | abstraction (Gradle is not _good_ good, but decent) beats
           | finding the magical incantation of configuration to get the
           | tool to do what you want.
        
           | lenkite wrote:
           | That is why maven offers a plugin model for your custom logic
           | that can be written in Java/Kotlin and a well defined
           | lifecycle model where you can configure your plugin
           | declaratively.
           | 
           | You can also download custom CLI tools and invoke them as
           | part of a well-defined build lifecycle.
        
             | gf000 wrote:
             | And then fail to do proper incremental builds, leaving you
             | with no choice but a faulty build or clean installing on
             | every occasion.
             | 
             | At the very least, I would move to Gradle which does have
             | proper knowledge of your build graph. But Mill is also a
             | good choice and fills the same niche, with the added
             | benefit that imperative-looking ordinary scala code will
             | simply become a parallelizable, cacheable build graph.
        
           | switchbak wrote:
           | I think folks just get used to Maven-induced constraints
           | (this applies to SBT, Bazel, others too). When you free
           | yourself from that you realize: builds just aren't all that
           | hard, it's often the tooling that becomes a real limitation.
           | 
           | Of course, sometimes the limitations are good: preventing you
           | from doing "the wrong thing", or encouraging cacheability,
           | etc. But as with any abstraction layer - getting a model that
           | fits across so many disparate use cases can be very
           | challenging.
        
         | henry700 wrote:
         | I hate wrangling with configuration to make an amalgamation of
         | plugins do what's expected in the expected order for my build;
         | Gradle is just code and a DSL
        
           | askonomm wrote:
           | If I would've gotten a Euro for every time "is just a DSL"
           | was a reason everything was hard to debug and prone to
           | failure, I'd have many Euros by now.
        
             | gf000 wrote:
             | Well, good luck debugging a multi-module maven pom file,
             | then. You can get terrible error messages from both, to be
             | honest.
        
           | imoverclocked wrote:
           | It's two DSLs which are versioned and whose behaviors are
           | different.
           | 
           | Gradle groovy is extremely permissive (eg: you can access
           | private class instance variables without even knowing that
           | you are doing so)
           | 
           | Kotlin lacks that permissive quality in exchange for much
           | easier introspection.
           | 
           | It's often trivial to move from one to the other but those
           | edge cases can find you in a codebase of any complexity.
        
         | chriswarbo wrote:
         | > maven is just a configuration file
         | 
         | Even better, Maven "POMs" are written in a common, standard
         | format (XML); so we can transform and manipulate it using off-
         | the-shelf tools, if we really want to. I've found this useful
         | e.g. in pre-commit hooks (tidy the formatting,
         | checking/linting, etc.); in Nix builds (e.g. removing the
         | version number, so it doesn't affect the hash and avoids
         | spurious rebuilds); etc. That was a nice bonus when I switched
         | some projects from SBT to Maven (due to SBT being wildly
         | unreproducible).
        
       | pbh101 wrote:
       | Anyone have a comparison to Bazel? They only compare to JVM-
       | centric tools eg Maven, sbt, Gradle.
        
         | frostirosti wrote:
         | Bazel is just such a nightmare for me. It's amazing when
         | someone understands it really well and can set things up. But
         | for anything short of that, being on the hook to fix or debug
         | things makes it a nightmare. That and trying to port anything
         | over from sbt, like scalafix for instance, to bazel is a pain.
         | 
         | Also too, bazel has this issue of googleability? like I feel
         | like I can take any build issue I've run into in sbt and find
         | the solution and an example by just searching, but with Bazel,
         | anything outside of the happy path is a recipe for pain
        
       | TheChaplain wrote:
       | Reminded me of this: https://xkcd.com/927/
        
       | dang wrote:
       | Related. Others?
       | 
       |  _Mill as a direct style build tool_ -
       | https://news.ycombinator.com/item?id=43943792 - May 2025 (9
       | comments)
       | 
       |  _Why does Mill use Scala?_ -
       | https://news.ycombinator.com/item?id=42997496 - Feb 2025 (75
       | comments)
       | 
       |  _Mill: A fast JVM build tool for Java and Scala_ -
       | https://news.ycombinator.com/item?id=41967734 - Oct 2024 (162
       | comments)
       | 
       |  _What 's So Special About the Mill Scala Build Tool_ -
       | https://news.ycombinator.com/item?id=38877882 - Jan 2024 (1
       | comment)
       | 
       |  _Mill: A Build Tool Based on Pure Functional Programming_ -
       | https://news.ycombinator.com/item?id=25925107 - Jan 2021 (1
       | comment)
       | 
       |  _Mill: Better Scala Builds_ -
       | https://news.ycombinator.com/item?id=16775545 - April 2018 (16
       | comments)
        
       | spullara wrote:
       | this is a horrific build file:
       | https://github.com/swaldman/c3p0/blob/0.11.x/build.mill
        
         | billmcneale wrote:
         | Yeah, hard to see how better this is than Gradle. If anything,
         | it's worse by the mere fact this is Scala, but it's really so
         | incredibly verbose to accomplish basic tasks such as upload to
         | Sonatype.
        
           | spullara wrote:
           | making it easier to generate maven poms I thought was a
           | reasonable idea 18 years ago but gradle and other tools all
           | went down the "making the build Turing complete" path.
           | 
           | https://github.com/spullara/graven/blob/master/pom.groovy
        
         | imoverclocked wrote:
         | You can write bad code in any language. Don't ask me how I know
         | :)
        
       | frant-hartm wrote:
       | I wonder what people use/need apart from the usual stuff in Maven
       | nowadays.
       | 
       | In the last 5 years, I didn't need anything more than:
       | 
       | - resource plugin - compiler plugin - jar plugin (jars, test
       | jars, javadoc jars) - surefire/failsafe - shade plugin for
       | repackaging to avoid classpath hell - assemble plugin - license
       | plugin
       | 
       | Most of the issues I had were with the shade/assemble/license
       | plugins.
       | 
       | I consider myself a Maven power-user and like the tool compared
       | to others (Gradle is too ant-like, resulting in non-standard
       | builds, sbt is just a torture tool).
       | 
       | With time, I concluded that the simpler it is, the better.
        
         | debarshri wrote:
         | I think you can make it 10 years. It is super robust. It just
         | works for java stuff.
        
         | switchbak wrote:
         | I've had the misfortune of having Maven forced on me for Scala
         | projects, I just can't agree with you. The overhead of starting
         | the compiler so often is a killer, and makes your builds much
         | slower. Unless there's been some improvement of Zinc/Bloop/Etc
         | with Maven since I've used it.
         | 
         | I think I would prefer to use Mill than Maven (I haven't used
         | Mill myself) ... going through the video tutorial, it's clear
         | that it's also a very simple system without some of the ancient
         | baggage of Maven (xml, too many plugins, etc).
        
           | vips7L wrote:
           | I've had sbt and scala forced upon me for Java projects and I
           | feel the exact opposite of you!
           | 
           | Sbt and Scalac are so slow they kill any productivity I could
           | have.
        
         | wellpast wrote:
         | I agree 100%.
         | 
         | I've been around for a while, I've used many different build
         | systems for JVM based builds (Java, Hybrid Java/Clojure, Scala)
         | and Maven is by far the simplest most solid.
         | 
         | The basic reason is it's commitment to being declarative.
         | 
         | I understand why programmers want imperative (we're
         | programmers) but it's just the wrong choice for a build system.
         | 
         | I've worked on many OSS projects. I've never pulled a Maven-
         | based project that didn't immediately build and immediately
         | load into my IDE. However for imperative based build systems
         | (Gradle, Ant, now Mill) it's almost inevitable that you won't
         | be able to get the build to work right away or pulled into your
         | IDE in a sensible way (as IDEs cannot read imperative
         | statemetns).
         | 
         | I've created many many build with Maven with many many
         | different demands (polygot codebase, weird deployment
         | artifacts, weird testing runtime needs, etc etc) and Maven has
         | never let me down. Yes, in some cases I've had to write my own
         | plugin but it was _good_ that I had to do that; it forced me to
         | ensure I really needed to -- the Maven plugin ecosystem is
         | already great and covers 90+% of use cases of builds.
         | 
         | I've met a lot of Maven naysayers and the disdain is almost
         | always either some weird aversion to XML (such a trivial reason
         | to choose a worser build system) and/or because the programmer
         | never took the time to understand the rather simple Maven
         | runtime semantics and architecture.
        
           | ackfoobar wrote:
           | > imperative based build systems (Gradle, Ant, now Mill)
           | 
           | Build code in Mill is pretty declarative. You're using the
           | word to mean "not 'pure, serialized data'".
           | 
           | > IDEs cannot read imperative statemetns
           | 
           | They can, however, run the code to dump the structure.
           | 
           | It's easy for code to embed pure data; on the flip side it's
           | hard to encode behaviour in serialized data. More often than
           | custom Maven plugins I see people just drop down to using
           | shell.
        
         | mindcrime wrote:
         | Ya know, I've directed a lot of criticism at Maven over the
         | years... and most of it well-founded, I believe, even in
         | hindsight. And yet, today, I find that of all the Java build
         | tools, Maven is my preferred one. Part of that is me,
         | normalizing the pain of Maven in some regards, and part of that
         | is places where they have improved the tool. But however you
         | break it down, it is indeed the case that for the most part
         | Maven "just works"(tm). That is, at least for Java. I don't do
         | a lot of Scala or Kotlin or anything, so no comment there. And
         | for Groovy, I'm usually doing Grails projects which default to
         | Gradle, so I tend to use Gradle in that context. But for plain
         | Java projects, I honestly find Maven to be the path of least
         | resistance.
        
         | Tainnor wrote:
         | My main problem with Maven is that it's dog slow and
         | incremental compilation doesn't really work, especially on CI.
         | For huge repos that's a real issue.
         | 
         | In a sense I feel that part of the microservice craze is due to
         | the fact that many of our build systems are not good enough to
         | allow us to work with huge monoliths efficiently. Gradle is a
         | bit better (definitely faster), but comes with additional
         | complexity. Haven't tried Mill.
        
       | Taranovski wrote:
       | Maintainability: Mill's config and custom logic is written in
       | concise type-checked JVM code - Inside - "why mill uses scala?"
       | LOL))
        
       | octopoc wrote:
       | IMO there should be one build system for each language and it
       | should be good at the basics, and if you need more then you
       | should write your own (minimal-dependency) build script _in the
       | same language as the code you 're building_, and in that system
       | you do things like generate build files for the big, complicated
       | thing you're trying to build.
       | 
       | In Java terms, if you have a big complicated Java repo that
       | requires lots of steps to build, you should have a separate Java
       | project in there just for building the main repo. That separate
       | Java project should be built and run with maven, and that
       | separate project can do all kinds of fancy things, but ultimately
       | it will be generating maven projects or calling maven with
       | special command line parameters or something like that.
       | 
       | I even put the logic for CI in my build project like this. It
       | makes everything reproducible and debuggable. How cool is it to
       | be able to put a breakpoint in your build script? How about
       | stepping through your CI code? Things are way simpler this way.
       | 
       | I eschew frameworks in this custom build tool, because the build
       | code should look conventional for whatever language it's written
       | in.
        
       | zcw100 wrote:
       | I don't know why I don't see anyone ever mention JeKa.
       | https://jeka.dev/
       | 
       | You don't have to learn a separate language or some weird config.
        
       | seanw444 wrote:
       | https://mill-build.org/mill/depth/parallelism.html#_mill_chr...
       | 
       | This is kinda funny. Generating a profile that is meant to be
       | visualized with a web browser's built-in profiler, not even an
       | HTML file. I guess if it's already built and works well
       | -\\_(tsu)_/-
        
         | akazantsev wrote:
         | That profiler is very powerful and used to analyze beasts like
         | Android and Chromium. It's a pro, not a con.
         | 
         | https://ui.perfetto.dev
        
           | seanw444 wrote:
           | I had no clue it was its own independent, comprehensive
           | project. Very cool.
        
       | switchbak wrote:
       | Not a lot of love for Mill in these comments. I'm interested in
       | what it has to offer.
       | 
       | I find SBT just has a lot of unnecessary abstractions and
       | complexity. It's so opaque that I'm sure I'm leaving a lot of
       | performance on the table with hidden antipatterns. Mill seems to
       | solve that by being 'boring' (in a good way). Being able to trace
       | what's happening in my IDE would be lovely - and something I
       | don't have in SBT or Maven either.
       | 
       | Now that we also have fast running native CLI tooling, I think
       | it's worth another look over SBT.
        
         | vips7L wrote:
         | A lot of people on the Java side have seen what being able to
         | script your build turns into with Gradle. They've also don't
         | want to learn Scala to do their build.
        
       | pi_22by7 wrote:
       | Honestly, I'm getting tired of the endless parade of "better"
       | build tools. Maven works fine for most of what I do, even if it's
       | occasionally painful. Gradle is... well, Gradle has its moments.
       | 
       | That said, Mill's performance claims sound interesting. If it
       | really can cut build times by 3-6x, that's really amazing. I've
       | wasted too much time in my life waiting for builds, especially on
       | larger projects.
       | 
       | The Scala thing is a bit of a turn-off though. I get that you
       | don't need to write Scala yourself, but now I'm dragging in the
       | Scala ecosystem just to build my Java project? Feels heavy.
       | 
       | The IDE integration sounds nice in theory - being able to
       | actually navigate and understand your build in IntelliJ would be
       | pretty sweet.
       | 
       | Still not sure the switching costs are worth it unless you're
       | really hitting Maven/Gradle pain points. But if I was starting a
       | new project from scratch, might be worth a look.
        
         | le-mark wrote:
         | When has build time been an issue though? Running tests have
         | taken the most time by far on every project I've ever worked
         | on.
        
       | HiPhish wrote:
       | Is it bootstrappable? I mean really bootstrappable, not "the
       | bootstrap script will download a binary from some server". This
       | is where both Maven and Gradle fail (at least the last time I
       | checked). Kotlin and Scala also have the problem that their
       | compilers themselves are not bootstrappable either.
        
       | smrtinsert wrote:
       | Please anything beyond gradle. Didn't hate maven but didn't love
       | it either. Happy to investigate alternatives
        
       | elric wrote:
       | Reading these comments I'm always amused by how different
       | people/teams have radically different needs & preferences, and
       | how other people seem to be dismissive of those. "I don't need
       | anything more than maven", "maven is too slow", "if it's not
       | bootstrappable I don't want it", "there should only be one
       | ultimate build tool", "I hate programming my build", etc.
       | 
       | These opinions are all valid, but only if they don't discount the
       | validity of other strategies. There is no universal law of
       | optimal build practices. There are cases where build performance
       | is critical, and others where it's not. There are cases where
       | configurability is important, and there are cases where it's not.
       | Etc.
       | 
       | Personally, I love having a programmable build in plain Java,
       | which is why I enjoy bld [1] these days. I'm probably the only
       | person you'll ever meet who actually enjoyed using ant, so you're
       | welcome to take my opinion with as much salt as you need to
       | digest that.
       | 
       | [1] https://rife2.com/bld
        
         | wiseowise wrote:
         | > There are cases where build performance is critical, *and
         | others where it's not.*
         | 
         | I'm curious about those.
        
           | Smar wrote:
           | Often CI results are not put to use immediately, making build
           | time irrelevant.
        
             | wiseowise wrote:
             | So you're okay with waiting a day to get "linter error,
             | you've put this on a wrong line, dumbass"?
        
         | kerblang wrote:
         | Ant worked well because it was extremely _explicit_: You had to
         | say what you wanted. This gave it a lot of flexibility. Unlike
         | some other tools, you aren't running in front of a train trying
         | to get it to stop and let you on. It doesn't go anywhere or do
         | anything until you say so. The cost was pretty much zero
         | defaults and a good bit of boilerplate.
         | 
         | I think a lot of people expected this from Gradle because the
         | idea of "build as programming" seemed like it would give that
         | stop-the-train-let-me-on-already ability. I don't know that it
         | really worked out that way. Maven is all about running devs
         | over, but it's faster than Gradle, which tries to start a
         | daemon just like SBT.
         | 
         | Anyhow... this bld thing looks interesting, thanks...
        
         | lucumo wrote:
         | > These opinions are all valid, but only if they don't discount
         | the validity of other strategies.
         | 
         | I strongly agree with this as a general principle in nearly all
         | technical discussions.
         | 
         | But also, if the discussion starts with declaring something is
         | better than everything else (as the title here), then there's
         | really no salvaging it anymore.
        
       | wiseowise wrote:
       | I just want `uv`/`npm`/`crate` for JVM. Is that too much to ask?
       | 
       | Can someone from Astral fix Java too, please?
        
         | Tainnor wrote:
         | JVM build tools have to do much more than just dependency
         | management because of how the JVM works (e.g. packaging
         | resources). It's not really comparable.
        
       | xg15 wrote:
       | Half expected this to be built in Rust...
        
       ___________________________________________________________________
       (page generated 2025-07-16 23:01 UTC)