Mesa is a virtual filesystem that mounts Mesa repositories as local directories without cloning. It is
ideal for agents, CI pipelines, and large monorepos where a full clone is impractical. Mesa supports macOS and Linux
via FUSE, as well as sandboxless environments via just-bash.
Effectively, when you’re running mesa, all your Mesa repos become just a directory on your system:
Mesa is early-stage, alpha software. We’ve tried our best to make it reliable, but you may encounter occasional
performance/stability issues.If you run into any issues, we urge you to open an issue.
How It Works
Mesa exposes your Mesa repositories as directories on your local machine. You can read files directly
and, when working on a change, create, modify, and delete files — all changes are automatically persisted
back to Mesa.
Installing
The quickest way to install mesa on macOS or Linux:
curl -fsSL https://mesa.dev/install.sh | sh
This will auto-detect your platform and install the latest stable release. Re-run the same command at any time to update.
On Linux, mesa mounts with the FUSE allow_other option so that other processes (e.g. editors, agents) can
access the mount. This requires user_allow_other to be enabled in /etc/fuse.conf.Uncomment or add the following line:If this is not set, mesa will fail to mount with a permission error.
Running in Docker
Mesa works in Docker containers, but slim and minimal base images
(like node:22-slim or debian:bookworm-slim) strip out system libraries
that Mesa needs at runtime. You’ll need to install them explicitly.
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
fuse3 \
libssl3 \
openssl \
&& rm -rf /var/lib/apt/lists/* \
&& update-ca-certificates
ca-certificates + openssl — TLS certificate store. Required for connections to Mesa’s API.
libssl3 — OpenSSL shared library, used for TLS.
fuse3 — Userspace FUSE library. Not needed if you’re only using just-bash.
If you skip these packages on a slim image, connections to Mesa’s API will fail with
errors like gRPC TLS configuration failed: transport error.
Getting Started
The easiest way to get started is to run:
On your first run, mesa mount will walk you through an interactive configuration wizard and store the config for future
use.
The default mount point is ~/.local/share/mesa/mnt on macOS. On Linux, it
defaults to $XDG_RUNTIME_DIR/mesa/mnt (typically /run/user/<uid>/mesa/mnt) when
available, falling back to ~/.local/share/mesa/mnt.
Try browsing a repository:
ls ~/.local/share/mesa/mnt/<your-org>/<your-repo>
When you’re done, hit Ctrl+C and mesa will clean up after itself.
You can control the log level with the MESA_LOG environment variable (uses
tracing filter syntax):MESA_LOG=debug mesa mount
Configuration
mesa is configured through a TOML config file. The configuration file is searched for in the following locations
(highest priority first):
$XDG_CONFIG_HOME/mesa/config.toml (Linux only)
$HOME/.config/mesa/config.toml
/etc/mesa/config.toml
You can override the path to the config file with the --config-path flag.
The default configuration file (with all options documented):
# The domain at which all Mesa services are exposed.
#
# You can specify a custom domain, if you are self-hosting Mesa.
service-domain = "mesa.dev"
# The path at which the filesystem should be mounted.
#
# Your organizations will be visible in this path.
mount-point = "/tmp/mesa/mnt"
# The POSIX owning user of the filesystem and all children.
#
# Note that, at this moment, we do not support user names.
uid = 1000
# The POSIX owning group of the filesystem and all children.
#
# Note that, at this moment, we do not support group names.
gid = 1000
# You can list out all organizations you are a member of under this section.
#
# Note that you will need to provide the organization API key. Additionally,
# you may also pass per-repo configurations.
#
# For example:
#
# [organizations.tyrell-corp]
# api-key = "<your-api-key>"
#
# [organizations.tyrell-corp.repos.nexus-replicants]
# rev = { bookmark = "main" } # or: rev = { change-id = "abc123..." }
[organizations]
[cache]
# Enable or disable the disk cache.
#
# NOTE: disabling the disk cache will result in a severe performance hit.
enabled = true
# The path to the cache directory.
#
# Mesa will store its cached data in this directory.
path = "/tmp/mesa/cache"
# Optionally set a maximum bound for the disk cache.
#
# This field supports rich values, so you can specify:
#
# max-size = "10GB'
#
# or
#
# max-size = "100MB"
# max-size =
# Daemon configuration.
[daemon]
# The path to the PID file for the daemon.
pid-file = "/tmp/mesa/mesa.pid"
# Configuration for the daemon logging.
[daemon.log]
# Where to write log output.
#
# target = { file = "/path/to/your/file" }
# uses the given file path to output logs
#
# target = "stdout"
# writes the log output to stdout
#
# target = "stderr"
# writes the log output to stderr
target = "stdout"
# Enable ANSI color in log output.
#
# color = "auto"
# decides based on whether the output file is a TTY (and $NO_COLOR)
#
# color = "always"
# forces the color to be enabled (disrespecting $NO_COLOR)
#
# color = "never"
# disables color output
color = "auto"
# Telemetry configuration for exporting OpenTelemetry traces.
[telemetry]
# Whether to send telemetry data to Mesa's servers.
#
# Although our default is to disable this field, we highly encourage you to
# enable vendor telemetry, as that allows us to catch bugs, as well as assist
# you better in case you run into any issues.
vendor = false
# If you wish to add an additional collector for your own internal telemetry,
# add it here.
#
# Example:
#
# collector-url = https://acme-corp.priv.mesa.dev/v1/traces
# collector-url =
Daemon Mode
You can run mesa mount as a background daemon:
Daemon logging can be configured in the [daemon.log] section of the config file:
[daemon.log]
# Where to write logs: "stdout", "stderr", or a file path.
target = { file = "/var/log/mesa.log" }
# Color mode: "auto", "always", or "never".
color = "auto"
CLI Commands
While mesa is running, you can manage changes and bookmarks from the CLI.
Create a new change on an existing bookmark:
cd path/to/your/repo && mesa new main
Create a new change from an existing change:
A change is Mesa’s equivalent of a git commit. Each change has a unique 32-character hex ID that mesa new and mesa edit write to stdout on success.
Example — start a feature branch and work on it:
# Create a bookmark, then a change on it
mesa bookmark create my-feature
CHANGE_ID=$(mesa new my-feature)
# Later, create a new change starting from the previous one
mesa new $CHANGE_ID
Switch to an existing bookmark:
Resume an existing change by ID:
Example — resume a change later:
mesa bookmark create my-feature
CHANGE_ID=$(mesa new my-feature)
# ... switch to another bookmark, do other work ...
mesa edit $CHANGE_ID
checkout is an alias for edit.
Create a new bookmark:
mesa bookmark create my-feature
List available bookmarks:
For detailed information, run mesa --help.