= Installation & IDE Setup

The standard method of installing Mill is to install a `./mill` <<_bootstrap_scripts,bootstrap script>>,
similar to `./gradlew` or `./mvnw` in other build tools.
This script can determine the best version to be used by a project (e.g. by
reading a `//| mill-version` header comment) and will use this exact Mill version.
If the determined Mill version is not installed locally, it will be downloaded automatically.

For all the examples in this documentation, there is a `download` link that provides
a zip file containing the full example ready to use. These examples come with a `./mill`
script you can use to immediately begin working with the project, automatically downloading and
caching a JVM and any additional dependencies as necessary.

== Bootstrap Scripts

The Mill example projects in this documentation come with `./mill` and `./mill.bat`
bootstrap script, included. You can also download the bootstrap script manually:

.Mac/Linux
[source,console,subs="verbatim,attributes"]
----
> curl -L {mill-download-url}/mill-dist-{mill-version}-mill.sh -o mill
> chmod +x mill
> ./mill version
{mill-version}
----

.Windows
[source,console,subs="verbatim,attributes"]
----
> curl.exe -L {mill-download-url}/mill-dist-{mill-version}-mill.bat -o mill.bat
> ./mill version
{mill-version}
----

[CAUTION]
--
*Don't use PowerShell 5.1 to install Mill!*
 +
PowerShell 5.1 is known to produce `UTF-16LE` encoded `.mill-version` files, which can't be read by Mill.
You should update to Powershell 7 or newer.
--

Downloading a `mill` bootstrap script to the root of your project repository makes it easier for
new contributors to build your project, as they don't have to install Mill before they can start.
Anyone who wants to work with the project can simply use the `./mill` script directly.

[source,console]
----
> ./mill --version
> ./mill __.compile # double underscore means compile all modules
----


In general, bootstrap scripts are the recommended way of installing Mill.
Similar to `./gradlew` or `./mvnw`, the `./mill` bootstrap script
reduces the chance of errors due to the installed version of Mill
being incompatible with the version expected by your build.
In-project bootstrap scripts are also useful for running Mill in CI/CD, ensuring
that your build server like Jenkins or Github Actions has the correct version of Mill
present to build, compile or test your code.

You can also configure a `//| mill-version` in your xref:cli/build-header.adoc[build header]
if you want to try a different version, but the best practice when upgrading is to just
update your bootstrap scripts which ensures the script version and Mill version are compatible.

If you are starting a new project using a Mill bootstrap script, you can use the
xref:cli/builtin-commands.adoc#_init[mill init] to initialize the project
folder with one of the Mill example projects. There are a wide range of example projects,
from hello-world to multi-module libraries to client-server web applications, and you can
pick one most similar to what you are doing so you can hit the ground running.

== Global Installation

You can also install the Mill bootstrap script globally on Mac and Linux via:

[source,console,subs="verbatim,attributes"]
----
> sudo sh -c '(curl -L {mill-download-url}/mill-dist-{mill-version}-mill.sh -o mill) > /usr/local/bin/mill && chmod +x /usr/local/bin/mill'
----

This can be useful when using Mill to run script files (written in xref:javalib/script.adoc[Java],
xref:scalalib/script.adoc[Scala], or xref:kotlinlib/script.adoc[Kotlin]) which may not belong
to any particular project. However, for projects that use Mill, it is recommended you use the
xref:#_bootstrap_scripts[per-project bootstrap scripts] discussed above to ensure that anyone
with the project codebase on disk will be able to build the project without needing a separate
installation

=== JVM Version

Mill uses Java `{default-mill-jvm-version}` by default, regardless of what is installed as your
system `java`. You can set a Java version in the xref:cli/build-header.adoc[build.mill header] via
a `mill-java-version` key if you wish to customize it:

``` scala
//| mill-jvm-version: temurin:24.0.1
```

The Mill JVM version is used for both evaluating the `build.mill` file as well as any
``JavaModule``s, ``ScalaModule``s, or ``KotlinModule``s you define. You can also specify a
xref:fundamentals/configuring-jvm-versions.adoc[per-module JVM version] if you need
finer-grained control. Mill supports every JVM version from `11` onward.

If you wish to use your system `java` installation, you can set `mill-jvm-version: system`.
Note that this is not recommended as it means your codebase may use different JVM versions
on different developer, CI, and production machines, potentially resulting in hard-to-debug
crashes and errors.



=== Mill Native and JVM Executables

The default Mill launcher configured above is a
xref:javalib/packaging.adoc#_building_native_image_binaries_with_graal_vm[Graal Native Image],
that provides faster startup and is able to run even on machines without Java installed.
Mill native executables are supported on the following OS/CPU combinations:

|===
| | Windows | Mac | Linux
| Intel | Y | Y | Y
| ARM |  | Y | Y
|===

Notably, Mill native executables _do not_ support Windows-ARM, due to limitations in the
upstream Graal Native Image tooling (see https://github.com/oracle/graal/issues/9215[oracle/graal#9215]).
If you are on a platform not supported by Mill's native executables, Mill uses the
JVM-based launcher instead. You can also opt-in to the JVM launcher on other platforms
by adding a a `-jvm` suffix on the Mill version:

[source,subs="verbatim,attributes"]
----
{mill-version}-jvm
----

Mill's JVM launcher imposes some Java startup overhead (~100ms) over the native launcher
when running Mill from the command line, and requires a JVM installed globally (version 17 or above)
in order to run.

== Bash/Zsh Tab Completion

You can set up Bash and Zsh tab completions by subsequently running the command:

[source,console,subs="verbatim,attributes"]
----
> ./mill mill.tabcomplete/install
----

This unpacks the completion script in `~/.local/share/mill/completion/mill-completion.sh`
and registers it in your `~/.bash_profile` and `~/.zshrc`. After that, doing `./mill <TAB>`
should begin showing possible modules and tasks for you to select at the command line:

image::basic/TabCompleteCommand.png[]

`./mill -<TAB>` or `./mill --<TAB>` will show the possible short and long flags
that Mill takes:

image::basic/TabCompleteFlag.png[]

Mill's command-line autocomplete also applies to custom xref:fundamentals/tasks.adoc#_commands[user-define commands],
such as `customCommand` below:

```scala
package build
import mill.*, javalib.*
import mainargs.arg
object foo extends JavaModule {
  def customCommand(
    @arg(doc = "string parameter to customCommand that controls this and that...")
    str: String,
    @arg(doc = "integer parameter to customCommand")
    int: Int) = Task.Command{
    // do stuff
  }
}
```

image::basic/TabCompleteCustomCommand.png[]

You can also choose to write the tab-completion script to a manually-specified path via:

[source,console,subs="verbatim,attributes"]
----
> ./mill mill.tabcomplete/install --dest <path>
----

When `--dest` is given, Mill simply generate the tab-completion script without registering it,
assuming you want to register the script yourself (e.g. by placing it in a relevant folder).

== Github Syntax Highlighting

Github doesn't yet have built-in support for syntax highlighting `.mill` files appropriately 
(see https://github.com/github-linguist/linguist/pull/7028[github-linguist/linguist#7028])
but you can set this up in your own projects by creating a `.gitattributes` file in the root
of your Github repository

[,console]
----
> echo '*.mill linguist-language=Scala' > .gitattributes
----

[#_ide_support]
== IDE Support
:link-metals: https://scalameta.org/metals/

Mill supports IntelliJ and VSCode and in general any client of the standard
https://build-server-protocol.github.io/[Build Server Protocol (BSP)].
Your IDEs may already auto-detect the Mill project and run this command on
behalf of you when opening/importing the project.

Mill can also generate project files for the Eclipse IDE that is not supporting
the Build Server Protocol (BSP).

=== IntelliJ

To use Mill with IntelliJ, first ensure you have the free
https://plugins.jetbrains.com/plugin/1347-scala[IntelliJ Scala Plugin]
installed. This is necessary as Mill build files are written in Scala,
even if you are using it to build a Java or Kotlin project.

Once you have the plugin installed, you can use IntelliJ to open any project
containing a Mill `build.mill` file, and IntelliJ will automatically load the
Mill build. If you have multiple build systems installed, Intellij may give you
choice which build system configuration to use for the import, which case select `BSP`:

image::basic/IntellijSelectBsp.png[]

This will provide support both for your application code,
as well as the code in the `build.mill`:

image::basic/IntellijApp.png[]

image::basic/IntellijBuild.png[]

If you make changes to your Mill `build.mill`, you can ask Intellij to load
those updates by opening the "BSP" tab and clicking the "Refresh" button

image::basic/IntellijRefresh.png[]

==== Explicit BSP installation

To prepare your project for IDEs, and in general any BSP client, you can also
run this command to generate the BSP configuration files:

[source,console]
----
> ./mill --bsp-install
----

This should not be necessary with IntelliJ and VSCode being able to identify and
load `build.mill` files by default, but can be useful in certain cases if you
are using a less-common editor that does not have this support builtin.

==== BSP output directory

When running Mill in BSP mode, default output directory is
`.bsp/mill-bsp-out` under the project workspace. This ensures BSP mode is not blocked by regular
Mill operations, however this also means that we need to compile the sources twice, which incurs
extra CPU and memory usage. If you'd rather reuse regular `out/` directory, set
the `MILL_NO_SEPARATE_BSP_OUTPUT_DIR` environment variable to `1` when running Mill in BSP mode.

==== IntelliJ IDEA XML Support

Apart from using the Build Server Protocol, you can also generate IDEA project
files directly with Mill. This is probably the preferred way if you work on
polyglot projects and need support for frameworks like AspectJ,
which are currently not specifically configured over BSP.

To generate IntelliJ IDEA project files into `.idea/`, run:

[source,console]
----
> ./mill mill.idea/
----

This will generate the XML files IntelliJ uses to configure your project

[source]
----
.idea
.idea/scala_settings.xml
.idea/mill_modules
.idea/mill_modules/.iml
.idea/mill_modules/mill-build.iml
.idea/mill_modules/test.iml
.idea/libraries
.idea/libraries/mill_scalalib_2_13_0_11_10_jar.xml
...
.idea/workspace.xml
.idea/modules.xml
.idea/scala_compiler.xml
.idea/misc.xml
----

After the files are generated, you can open the folder in IntelliJ to load the project
into your IDE. If you make changes to your Mill `build.mill`, you can update the project config
those updates by running `./mill mill.idea/` again.

=== VSCode

To use Mill with VSCode, first ensure you have the free
https://marketplace.visualstudio.com/items?itemName=scalameta.metals[Metals VSCode Scala language server]
installed. This is necessary as Mill build files are written in Scala,
even if you are using it to build a Java project.

NOTE: Mill in VSCode only supports Java and Scala. Kotlin users are advised to use the free  IntelliJ IDEA Community Edition

Once you have the language server installed, you can ask VSCode to open any folder
containing a Mill `build.mill` file, and VSCode will ask you to import your
Mill build. This will provide support both for your application code,
as well as the code in the `build.mill`:

image::basic/VSCodeApp.png[]

image::basic/VSCodeBuild.png[]

If you make changes to your Mill `build.mill`, you can ask VSCode to load
those updates by opening the "BSP" tab and clicking the "Refresh" button

image::basic/VSCodeRefresh.png[]

=== Eclipse IDE

There is no direct support yet for Mill or the
https://build-server-protocol.github.io/[Build Server Protocol (BSP)] from any
plug-in in the https://eclipseide.org[Eclipse IDE]. Instead, Mill can generate
project files for Java projects. To use them, first ensure you have the
https://projects.eclipse.org/projects/eclipse.jdt[Java Development Tools (JDT)]
installed in your IDE which enables the support for Java projects.

NOTE: Scala and Kotlin are not supported by this generator. For these languages
use either VSCode (supporting Scala) or IntelliJ IDEA (supporting both Scala
and Kotlin).

Since Mill build files are written in Scala and there is no Eclipse plug-in
providing support for Scala, Mill itself or the Build Server Protocol (BSP)
actively maintained, this won't provide assistance in `build.mill` files.

To generate Eclipse project files, run:

[source,console]
----
> ./mill mill.eclipse/
----

This will generate the XML and preference files Eclipse uses to configure
projects. The command output will also provide you with the information on how
many Eclipse projects were generated and their respective location.

[source]
----
.settings/org.eclipse.core.resources.prefs
.settings/org.eclipse.jdt.core.prefs
.classpath
.project
----

CAUTION: Be aware that, contrary to IntelliJ IDEA, in Eclipse there won't be
only one project for your whole Mill project, but multiple ones depending on
your project structure. There might be dependencies between the generated
Eclipse projects.

After the files are generated, you can import the project(s) into an existing
Eclipse workspace in your IDE.

image::basic/EclipseImportProjects.png[]

You can choose to import all generated Eclipse projects inside the Mill project
folder or only a subset.

image::basic/EclipseSelectProjects.png[]

If you make changes to you Mill build files, you can update the project files
by running `./mill mill.eclipse/` again. Afterwards, refresh the projects
inside the Eclipse workspace by selecting them and hitting `F5`.

=== Other Editors / Metals

A lot of other editors may work too, since {link-metals}[Metals], the Language Server for Scala has built-in support for BSP. See the <<_ide_support,general instructions>> above.

=== Debugging IDE issues

Mill's BSP IDE integration writes to log files under
`.bsp/mill-bsp-out/mill-bsp/`, where you can find various information about what's
going on. It contains regular Mill output accompanied by additional BSP
client-server communication details. This can be useful to look at if your
IDE fails to import your Mill project


== Setting up Mill in CI

=== CI Bootstrap Scripts

Due to Mill's usage of xref:#_bootstrap_scripts[Bootstrap Scripts], you typically do not
need to setup anything in your CI system to make Mill work. Any Mill project should be
buildable via `./mill` on your CI machines without needing to first install Java, Mill,
or other dependencies, and the `./mill` bootstrap script will download these dependencies
as necessary.

=== FORCE_COLOR

One thing that you should set up manually is to enable a https://force-color.org/[FORCE_COLOR]
environment variable in your CI system. For example, in Github Actions this can be configured
in your workflow `.yml` file via:

```yaml
env:
  FORCE_COLOR: '1'
```

`FORCE_COLOR` ensures Mill produces ANSI-colored output logs despite being called
programmatically in on your CI machines. Most CI systems process and render ANSI
colors nicely in the browser, and this can make your CI logs much easier to read
than if they were black-and-white:

**Without FORCE_COLOR**

image::basic/ForceColor0.png[]

**With FORCE_COLOR=1**

image::basic/ForceColor1.png[]

=== Re-using the `out/` Folder

Mill caches its outputs locally in the xref:fundamentals/out-dir.adoc[out/ folder]. You
can preserve this `out/` folder between CI workers, e.g. to allow a subsequent CI worker
to use a previous worker's cached results, or to perform initial compilation on one worker
then share the compiled output with downstream workers.

For example, for Github Actions you may configure `out/` folder uploading via

```yaml
  - uses: actions/upload-artifact@v4
    with:
      name: build-out
      path: out/
```

And downloading via

```yaml
  - uses: actions/download-artifact@v4
    with:
      name: build-out
      path: out/
```


=== Github Actions Test Reports

If you use Github Actions for CI, you can use https://github.com/mikepenz/action-junit-report in
your pipeline to render the generated `test-report.xml` files nicely on Github. See
https://github.com/com-lihaoyi/mill/pull/4218/files for an example integration

=== Selective Test Execution

To minimize the number of unnecessary tests that you run on CI jobs, you should
use xref:large/selective-execution.adoc[Selective Test Execution] for any large multi-module
codebase. This allows you to limit the tests that run on your codebase to those in modules
downstream of the code you changed, allowing you to save time and resources by not wastefully
running tests that could not possibly be affected by your code change.


== Using Mill without access to Maven Central

Under some circumstances (e.g. corporate firewalls), you may not have access maven central.
The typical symptom will be error messages which look like this;

[source]
----
mill.scalalib.JvmWorkerModule.classpath
Resolution failed for 1 modules:
--------------------------------------------
  com.lihaoyi:mill-libs-scalalib-worker_2.13:0.11.1
        not found: C:\Users\partens\.ivy2\local\com.lihaoyi\mill-libs-scalalib-worker_2.13\0.11.1\ivys\ivy.xml
        download error: Caught java.io.IOException (Server returned HTTP response code: 503 for URL: https://repo1.maven.org/maven2/com/lihaoyi/mill-libs-scalalib-worker_2.13/0.11.1/mill-libs-scalalib-worker_2.13-0.11.1.pom) while downloading https://repo1.maven.org/maven2/com/lihaoyi/mill-libs-scalalib-worker_2.13/0.11.1/mill-libs-scalalib-worker_2.13-0.11.1.pom
----

It is expected that basic commands (e.g. clean) will not work, as Mill saying it is
unable to resolve it's own, fundamental, dependencies from the default Maven Central
JVM package repository. Under such circumstances, you
will normally have access to some proxy, or other corporate repository which resolves
maven artifacts.

To resolve this, you can set an environment variable `COURSIER_REPOSITORIES` (see coursier docs)
to point at your own server that mirrors the Maven Central artifacts.
The below command should pass the environment variable to the `mill` command.

[source,console]
----
> COURSIER_REPOSITORIES=https://packages.corp.com/artifactory/maven/ mill resolve _
----

If you are using bootstrap script, a more permanent solution could be to set the environment variable
at the top of the bootstrap script, or as a user environment variable.

== Updating Mill

The recommended way to manage your Mill version is to rely on the `DEFAULT_MILL_VERSION` defined
in your `./mill` and `./mill.bat` bootstrap scripts. These can be updated via the builtin command
`updateMillScripts`:

```console
> ./mill updateMillScripts 1.1.0
```

In general, managing your Mill version via your `./mill` bootstrap scripts is most reliable, as
it ensures the bootstrap script and the Mill version you use are always in sync. However, Mill
also provides other ways of overriding the Mill version used, which we will discuss below:

=== Overriding your Mill Version

Apart from the version defined in your bootstrap script, you
can also override the Mill version via use a `mill-version` key in your xref:cli/build-header.adoc[]
or a `.mill-version` file. The file path `.config/mill-version` is also supported. If neither is provided,
the `./mill` bootstrap script will use the `DEFAULT_MILL_VERSION` it has built in.

To choose a different Mill version on an ad-hoc basis, e.g. for experimentation, you can pass
in a `MILL_VERSION` environment variable, e.g.

[source,console]
----
> MILL_VERSION=0.5.0-3-4faefb mill __.compile
----

or

[source,console]
----
> MILL_VERSION=0.5.0-3-4faefb ./mill __.compile
----

to override the Mill version manually. This takes precedence over the version
specified in `./mill`, `.config/mill-version` or `.mill-version`

In general, we recommend you manage your Mill version via your `./mill` bootstrap scripts and
update it via `./mill updateMillScripts`. That is the most reliable approach, and avoids issues
that may be caused by incompatibilities between your `./mill` script and the `mill-version`
you override.


=== Automatic Mill updates

If your project is hosted on GitHub, GitLab, or Bitbucket, you can use
https://github.com/scala-steward-org/scala-steward[Scala Steward] to
automatically open a pull request to update your Mill version (in
`.mill-version` or `.config/mill-version` file), whenever there is a newer version available.

TIP: Scala Steward can also
xref:scalalib/dependencies.adoc#_keeping_up_to_date_with_scala_steward[scan your project dependencies]
and keep them up-to-date.

=== Unstable Development Releases

In case you want to try out the latest features and improvements that are
currently in the main branch, unstable versions of Mill
are available as versions named:

* `+{stable-version}-{commits-since-stable-version}-{commit-hash}+`

For example, `0.12.5-193-b4d975` is an unstable release after `0.12.5`, with `193`
additional commits, on commit hash `b4d975`.

The list of unstable releases can be seen on Maven Central:

* https://repo1.maven.org/maven2/com/lihaoyi/mill-dist

Or find the latest unstable version here:

* https://central.sonatype.com/artifact/com.lihaoyi/mill-dist

You can update your `.mill-version` to the unstable version and the bootstrap script
will download it for you to try it out in your project.



== Other installation methods

No other installation methods of Mill are officially supported. Homebrew, Pacman, Scoop,
Docker, Coursier, etc. are maintained by third parties and cannot be guaranteed to work.
Please use the bootstrap script installation described on this page. If you have issues
with installing Mill from other package managers, please open an issue on their respective
codebase
