github backend
The github backend installs a tool from the files attached to a GitHub repository's releases. mise picks the asset for your OS and architecture, verifies it, and extracts it. The gitlab and forgejo backends share this implementation and accept the options on this page.
If the tool has a registry shorthand, such as ripgrep, prefer it: the registry entry already names a backend and the options the tool needs. Use github:owner/repo for a tool without a shorthand, or to choose this backend yourself.
Usage
Install ripgrep in the current project, then run it:
mise use github:BurntSushi/ripgrep
mise exec -- rg --versionThis writes the following to mise.toml. Add -g to mise use for a global tool.
[tools]
"github:BurntSushi/ripgrep" = "latest"List the available versions and pin one:
mise ls-remote github:BurntSushi/ripgrep
mise use github:BurntSushi/[email protected]A version is the release tag without its leading v; see version_prefix for other tag formats.
To pass tool options on the command line, append them in brackets. Quote the argument so the shell does not expand the brackets:
mise use 'github:oxc-project/oxc[matching=oxlint,rename_exe=oxlint]@apps_v1.69.0'mise writes the options into the tool's entry in mise.toml. Public releases need no token. For private repositories, GitHub Enterprise Server or rate-limit errors, see GitHub tokens.
How mise picks an asset
For each install, mise downloads one release asset:
- If a
urlis set for the platform, mise downloads that URL and selects no asset. - If
asset_patternis set, mise downloads the asset whose name matches it. - Otherwise mise keeps the assets that pass
matchingandmatching_regex, if set, and scores each one. The score rewards a match for your OS, CPU architecture and C library (glibc or musl on Linux, MSVC on Windows), archive formats it extracts well, and names that start with the repository name. It penalizes debug and test builds, checksum and signature files, and macOS.appbundles on other systems or withno_app. The highest score wins, and a tie goes to the shortest name.
Most tools install without any option:
mise install github:user/repoIf mise picks the wrong asset, narrow the candidates with matching or name the asset with asset_pattern. When nothing matches, the error lists the release's assets.
mise then verifies the download. It checks the digest GitHub reports for the asset, or a checksum file published in the same release, and on public GitHub it checks GitHub artifact attestations when the release has them. See Verification.
Tool options
Set these options on the tool's entry in [tools], or inline as github:owner/repo[key=value]. The gitlab and forgejo backends accept all of them except the GitHub-only verification options; the gitlab and forgejo pages list what behaves differently there. Options that every backend accepts, such as postinstall and os, are described in tool options.
| Option | Use it to |
|---|---|
asset_pattern | Name the asset to download |
matching, matching_regex | Narrow the assets that autodetection chooses from |
no_app | Prefer a command-line archive over a macOS .app bundle |
additional_asset_patterns | Extract more archives from the same release into the install |
version_prefix | Read versions from tags with a prefix other than v |
prerelease | Include prereleases |
version_order | Order versions by semantic version |
url | Download a URL instead of a release asset on one platform |
format | Set the archive format |
strip_components | Remove leading directories when extracting |
bin_path | Name the directory that holds the executables |
bin | Name a single-file download |
rename_exe | Rename executables extracted from an archive |
filter_bins | Put only some executables on PATH |
checksum, size | Pin the artifact's digest and size |
github_attestations | Skip GitHub artifact attestation checks for one tool (GitHub only) |
slsa_signer_identity, slsa_signer_issuer | Verify SLSA provenance (GitHub only) |
api_url | Use GitHub Enterprise Server or another forge host |
Selecting assets
asset_pattern
The name of the asset to download, with * matching any run of characters and ? matching one character. The pattern must match the whole name, and when it matches several assets, mise picks the shortest name. It replaces autodetection, so a pattern that names one platform, as below, works only on that platform:
[tools]
"github:cli/cli" = { version = "latest", asset_pattern = "gh_*_linux_amd64.tar.gz" }For a configuration that works everywhere, set the pattern per platform or use matching. The pattern is a template, so it can include the version, OS and architecture.
matching
Keeps only assets whose names contain this text, then lets autodetection pick your OS and architecture from what is left. Use it when a release ships several tools for each platform, such as oxlint-* and oxfmt-* archives: one configuration then works on every platform.
[tools]
"github:oxc-project/oxc" = { version = "apps_v1.69.0", matching = "oxlint", rename_exe = "oxlint" }The test is a case-sensitive substring, so matching = "tool" also keeps tool-extras-* assets. Use matching_regex with an anchor for an exact prefix. If no asset for your platform passes the filter, the install fails with an error that names the filter. When asset_pattern is also set, mise uses it and ignores matching and matching_regex without a warning. SLSA provenance lookups use the same filter, so each binary of a multi-binary release is verified against its own provenance file.
matching_regex
Like matching, but the asset name must match a regular expression. The match is case-sensitive; start the expression with (?i) to ignore case. When both options are set, an asset must pass both. An invalid expression fails the install.
[tools]
"github:oxc-project/oxc" = { version = "apps_v1.69.0", matching_regex = "^oxlint-", rename_exe = "oxlint" }no_app
On macOS, prefers a standalone archive over a .app bundle, such as an Xcode extension, during autodetection. mise already avoids .app bundles on other systems. It has no effect when asset_pattern is set.
[tools."github:nicklockwood/SwiftFormat"]
version = "latest"
rename_exe = "swiftformat"
no_app = true # use swiftformat.zip, not SwiftFormat.for.Xcode.app.zipadditional_asset_patterns
Downloads more archives from the same release and extracts them into the primary asset's install directory, in the order listed. Use it when a project splits one installation across a base archive and add-on archives. For example, Ollama's ROCm support for Linux on x64 is an archive laid over the normal Ollama archive:
[tools."github:ollama/ollama"]
version = "latest"
[tools."github:ollama/ollama".platforms]
linux-x64 = {
additional_asset_patterns = ["ollama-linux-amd64-rocm.tar.zst"],
}Each pattern uses the same wildcards and templates as asset_pattern. If a pattern matches several assets, mise picks the shortest name, so make each pattern specific to one archive. The value is an array or a comma-separated string.
The extra assets must be archives. mise extracts them without the primary asset's strip_components, bin and rename_exe, and a file in a later archive replaces the same path from an earlier one. mise lock records the URL and checksum of every extra archive, and mise install --locked fails when one is missing from the lockfile.
Choosing versions
version_prefix
The text in front of the version in release tags. Without it, mise removes a leading v from each tag, and on GitHub it also removes a prefix that repeats the repository name, as in the tag [email protected]. Set it when a repository uses another prefix:
[tools]
"github:user/repo" = { version = "latest", version_prefix = "release-" }With version_prefix = "release-", mise lists only tags that start with release-, shows the tag release-1.0.0 as 1.0.0, and installs that tag for mise use github:user/[email protected]. Set version_prefix = "" to keep tags exactly as published, including a leading v.
prerelease
By default, mise leaves releases that GitHub marks as prereleases out of mise ls-remote, latest and version prefixes. Set prerelease = true to include them:
[tools]
"github:myorg/mytool" = { version = "latest", prerelease = true }latest then resolves to the newest release, prereleases included, instead of the release GitHub marks as Latest, and a prefix such as 1.2 also matches prerelease tags under it. Use it for a repository whose active releases are all prereleases, or to follow release candidates. Draft releases are never listed.
To include prereleases for every tool, set the prereleases setting (MISE_PRERELEASES=1). For a single listing, run mise ls-remote --prerelease.
version_order
By default, mise ls-remote lists releases in the order they were published. Set version_order = "semver" when a repository publishes backports after newer releases, so that the list and prefixes such as 1.2 follow semantic version order:
[tools]
"github:owner/tool" = { version = "1.2", version_order = "semver" }latest still resolves to the release GitHub or Forgejo marks as latest when there is one. See version ordering.
Per-platform options
Set an option under platforms.<os>-<arch> to use it on that platform only. A platform value overrides the top-level one. The key uses mise's names, linux, macos or windows and x64 or arm64; mise also accepts darwin, amd64, x86_64 and aarch64.
[tools."github:cli/cli"]
version = "2.100.0"
[tools."github:cli/cli".platforms]
linux-x64 = {
asset_pattern = "gh_*_linux_amd64.tar.gz",
checksum = "sha256:REPLACE_WITH_THE_64_HEX_DIGIT_DIGEST",
}
macos-arm64 = {
asset_pattern = "gh_*_macOS_arm64.zip",
checksum = "sha256:REPLACE_WITH_THE_64_HEX_DIGIT_DIGEST",
}These options can be set per platform: asset_pattern, additional_asset_patterns, url, no_app, format, strip_components, bin_path, bin, rename_exe, filter_bins, checksum and size. The other options apply to every platform.
url
Set platforms.<os>-<arch>.url to download that URL instead of selecting a release asset. The URL is a template:
{{ version }} is the resolved version, even when you request latest.
[tools."github:owner/repo"]
version = "latest"
platforms.macos-arm64.url = "https://downloads.example.com/tool/{{ version }}/tool-macos-arm64.tar.gz"Include any tag prefix, such as v, in the URL yourself. This backend ignores a top-level url, so set it under each platform. mise extracts the download but never builds it, so the URL must point to a prebuilt archive or binary. You can lay release assets over it with additional_asset_patterns. When every platform you support sets url, mise lists releases even if they have no assets; see How versions are listed.
Extracting and naming executables
format
The archive format, such as tar.gz, tar.xz or zip. Set it when an asset name has no extension or a misleading one; otherwise mise detects the format from the name. Use raw for a file that is not an archive.
[tools]
"github:owner/repo" = { version = "1.0.0", asset_pattern = "tool-linux-x64", format = "tar.gz" }strip_components
The number of leading directories to remove when extracting an archive:
[tools]
"github:cli/cli" = { version = "latest", strip_components = 1 }When neither strip_components nor bin_path is set, mise removes one level by itself if the archive holds a single top-level directory and no files, as ripgrep's archives do (ripgrep-14.1.1-x86_64-unknown-linux-musl/rg).
bin_path
The directory, relative to the install directory, that holds the executables. Set it when mise does not find them. mise applies it after strip_components, and setting it turns off the automatic stripping.
For an archive laid out as tool-1.0.0/bin/tool, set strip_components = 1 and bin_path = "bin", as below, or keep the outer directory with bin_path = "tool-{{ version }}/bin".
[tools."github:cli/cli"]
version = "latest"
strip_components = 1
bin_path = "bin" # after the archive's outer directory is removedbin_path is a template, for when the directory name includes the version, OS or architecture:
[tools."github:pizlonator/fil-c"]
version = "latest"
# such as filc-0.681-linux-x86_64/build/bin
strip_components = 0
bin_path = 'filc-{{ version }}-{{ os() }}-{{ arch(x64="x86_64", arm64="aarch64") }}/build/bin'When bin_path is not set, mise puts these directories on PATH, using the first rule that applies:
bin/in the install directory, if it exists.Contents/MacOSin the install directory, for a.appbundle whose outer directory was stripped.- The install directory, if it directly contains an executable file.
- Every immediate subdirectory that qualifies: a
*.appdirectory contributes itsContents/MacOS, and any other subdirectory contributes itsbin/, or itself if it directly contains an executable. - The install directory.
When filter_bins is set, only its .mise-bins directory goes on PATH.
Naming the executable
| Download | Option | Example |
|---|---|---|
| A single binary file | bin | bin = "mytool" |
| An archive with one executable | rename_exe | rename_exe = "yt-dlp" |
| An archive with several executables | rename_exe as a table | rename_exe = { "ols-*" = "ols", "odinfmt-*" = "odinfmt" } |
bin
The name to give a downloaded single-file binary. It can include a directory, such as bin/mytool. mise already removes OS and architecture suffixes from single-binary downloads, so docker-compose-linux-x86_64 installs as docker-compose with no option. Set bin only when you want another name:
[tools."github:owner/repo"]
version = "1.0.0"
bin = "mytool" # install the downloaded file as mytoolrename_exe
Renames an executable after an archive is extracted. The string form renames the tool's main executable: the one named after the repository, else one whose name contains the repository name, else the first executable mise finds.
[tools."github:yt-dlp/yt-dlp"]
version = "latest"
asset_pattern = "yt-dlp_linux.zip"
rename_exe = "yt-dlp"When an archive ships several executables that you want under plain names, use the table form. Each key is an exact file name or a glob, and each value is the new name:
[tools."github:DanielGavin/ols"]
version = "latest"
# the archive holds ols-x86_64-unknown-linux-gnu and odinfmt-x86_64-unknown-linux-gnu
rename_exe = { "ols-*" = "ols", "odinfmt-*" = "odinfmt" }mise warns about a key that matches nothing, and restores the executable bit that some archives, such as ZIP files, drop.
filter_bins
Puts only the named executables on PATH. mise links them into a .mise-bins directory inside the install and puts only that directory on PATH, so other executables in the archive, such as pandoc-lua and pandoc-server, stay hidden. The value is an array or a comma-separated string, and mise warns about a name it cannot find.
[tools]
"github:jgm/pandoc" = { version = "latest", filter_bins = "pandoc" }
"github:owner/repo" = { version = "latest", filter_bins = ["tool", "helper"] }On Windows, name the file with its extension (filter_bins = "pandoc.exe"). The entries in .mise-bins are copies there, so mise x and shims start the installed file instead, and it finds the DLLs and data beside it. A shell that finds the copy on PATH by itself, as with mise activate, still runs the copy. Each copy records which file it came from when it is installed, so reinstall a tool installed by an older mise (mise install --force) to get this.
Verification
When GitHub reports a digest for the asset, or the release publishes a checksum file that lists it, mise checks the download against it. When lockfiles are enabled, mise records the checksum in mise.lock and checks later installs against it. On public GitHub mise also checks GitHub artifact attestations. The options below pin values by hand, add SLSA provenance checks, or turn the attestation check off.
checksum
Usually you do not need this: mise lock records the URL and checksum for every platform. Set checksum to pin one artifact by hand, as <algorithm>:<hash> with an algorithm such as sha256, sha512 or blake3. A checksum describes one version and one asset, so pin the version, and set it per platform when you support several:
[tools."github:owner/repo"]
version = "1.0.0"
asset_pattern = "tool-1.0.0-x64.tar.gz"
checksum = "sha256:REPLACE_WITH_THE_64_HEX_DIGIT_DIGEST"size
The expected size of the asset in bytes. The install fails when the download has a different size. A size check catches truncated downloads, but it does not replace a checksum.
[tools]
"github:owner/repo" = { version = "1.0.0", checksum = "sha256:REPLACE_WITH_THE_64_HEX_DIGIT_DIGEST", size = "12345678" }github_attestations
By default, mise checks GitHub artifact attestations when a release asset has them. Set github_attestations = false to skip that check for one tool while keeping it on for the others:
[tools]
"github:myorg/mytool" = { version = "latest", github_attestations = false }Use it as a temporary workaround when GitHub's attestation service or trusted root data makes installs fail. Checksums, and SLSA provenance when it is configured, are still checked. If mise.lock records github-attestations provenance for the tool, run mise lock again after setting this option: otherwise the install fails, because the lockfile requires a check the tool has turned off. The github.github_attestations setting turns the check off for every tool. This option is GitHub only.
slsa_signer_identity and slsa_signer_issuer
To verify SLSA provenance published with a release, set the certificate identity and the OIDC issuer that you expect for the release workflow:
[tools."github:myorg/mytool"]
version = "latest"
slsa_signer_identity = "https://github.com/myorg/mytool/.github/workflows/release.yml@refs/tags/v{{ version }}"
slsa_signer_issuer = "https://token.actions.githubusercontent.com"The identity must match the workflow ref in the certificate exactly. It is a template, so {{ version }} is the resolved version.
Without both options, mise skips SLSA provenance and uses the other checks. A lockfile entry that records a checksum and SLSA provenance installs without verifying again, unless locked_verify_provenance is set; that setting also makes missing signer options an error. These options are GitHub only.
Templates
asset_pattern, additional_asset_patterns, url, bin_path and slsa_signer_identity are Tera templates. Write values in double braces:
{{ version }}: the resolved version, without the tag prefix{{ os() }}:linux,macosorwindows{{ arch() }}:x64orarm64
os and arch are functions, so include the parentheses. Each takes keyword arguments that rename a value, for a project that uses other names: {{ os(macos="darwin") }} or {{ arch(x64="x86_64", arm64="aarch64") }}. Use a single-quoted TOML string when the template contains double quotes, as in the bin_path example above.
Single-brace placeholders deprecated
Single-brace placeholders such as {version} and {x86_64_arch} are deprecated. mise has warned about them since 2026.3.0 and will stop accepting them in 2027.3.0. Replace them as follows:
| Deprecated | Replacement |
|---|---|
{version} | {{ version }} |
{os} | {{ os() }} |
{arch} | {{ arch() }} |
{darwin_os} | {{ os(macos="darwin") }} |
{amd64_arch} | {{ arch(x64="amd64") }} |
{x86_64_arch} | {{ arch(x64="x86_64", arm64="aarch64") }} |
{gnu_arch} | {{ arch(x64="x86_64") }} |
Installing several tools from one release
If the assets make up one installation, such as a base archive and an add-on, use additional_asset_patterns. If they are separate tools, give each one a tool alias that points at the same repository, and select its asset with matching:
[tool_alias]
oxlint = "github:oxc-project/oxc"
oxfmt = "github:oxc-project/oxc"
[tools.oxlint]
version = "apps_v1.69.0"
matching = "oxlint"
rename_exe = "oxlint"
[tools.oxfmt]
version = "apps_v1.69.0"
matching = "oxfmt"
rename_exe = "oxfmt"Each alias is a separate tool with its own version and install directory. If one binary's name is part of another's, use matching_regex with an anchor, such as ^oxlint-, instead of matching.
Two entries for the same github:owner/repo with different matching values do not work: mise treats them as one tool, uses the first entry's options, and never installs the other binary.
GitHub Enterprise Server
Set api_url to your server's API, and provide a token for that host as described in GitHub tokens. mise lists releases, looks up assets and downloads them through that API. GitHub artifact attestations are not checked for a custom api_url, because GitHub Enterprise Server does not serve them.
api_url
The base URL of the API. It defaults to https://api.github.com here, https://gitlab.com/api/v4 on the gitlab backend and https://codeberg.org/api/v1 on the forgejo backend.
[tools]
"github:myorg/mytool" = { version = "latest", api_url = "https://github.mycompany.com/api/v3" }How versions are listed
mise ls-remote lists the repository's releases that have at least one asset attached. mise installs from release assets and never from GitHub's generated source archives, so a release without assets has nothing to install. A release whose assets do not cover your platform is still listed, so the version list is the same on every machine and cross-platform lockfiles work. Draft releases are never listed, and prereleases only with prerelease.
If every platform you support sets url, mise lists releases whether or not they have assets. A url for only some platforms also lists asset-less releases everywhere, and installing one of them on a platform without a url fails.
mise reads one page of 100 releases. It reads more, up to three pages, only while it has not found a stable release with assets. Set MISE_LIST_ALL_VERSIONS=1 to read every page. For public repositories, mise reads release lists from mise-versions, and asks the GitHub API only if mise-versions fails to answer, unless use_versions_host is off. mise-versions serves the newest 1,000 releases of a repository; to list older ones, turn use_versions_host off.
Settings
The other settings in the github group choose and create tokens; see GitHub, GitLab, and Forgejo tokens.
Set these under [settings] in a config file, with mise settings set, or with a setting's environment variable where it has one. See which value wins when a setting is set in more than one place.
github.github_attestations
Verify GitHub artifact attestations for github backend tools.
- Type:
boolean - Default:
true - Environment variable:
MISE_GITHUB_GITHUB_ATTESTATIONS
Attestations are checked only when this setting, the global
github_attestations
setting and the tool's own github_attestations option are all true; set the
option to false to skip one tool. Tools with a custom api_url, such as those
on GitHub Enterprise Server, are not checked, because that API has no
attestations endpoint.
github.slsa
Verify SLSA provenance for github backend tools that name a signer.
- Type:
boolean - Default:
true - Environment variable:
MISE_GITHUB_SLSA
Provenance is checked only for tools that set
slsa_signer_identity and slsa_signer_issuer,
and only while the global slsa setting is
true.
Implementation: src/backend/github.rs.