> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mesa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# fs.mount()

> Mount one or more repositories as a Mesa virtual filesystem.

`mesa.fs.mount(...)` returns a `MesaFileSystem` backed by Mesa's native filesystem implementation.

```ts theme={null}
import { Buffer } from 'node:buffer';
import { Mesa } from '@mesadev/sdk';

const mesa = new Mesa({ org: 'acme' });
const fs = await mesa.fs.mount({ repos: [{ name: 'app' }] });

const data = await fs.readFileBuffer('/acme/app/README.md');
console.log(Buffer.from(data).toString('utf8'));
```

Under the hood, `mount()` signs a single short-lived, repo-scoped access token (JWT) locally from your API key and connects to the VCS backend. The token's repo scope is encoded as full `org/repo` names, so signing does not resolve repository ids over the network. The mount uses that one token for its whole lifetime: there is no background refresh and no credential hot-swap, so once the token expires the mount stops authenticating. Choose a `ttl` that covers the mount's work. No server-side credential is created or revoked.

## Options

<ParamField path="repos" type="RepoConfig[]" required>
  Repositories to mount. The array must be non-empty.
</ParamField>

<ParamField path="ttl" type="number | undefined">
  Lifetime of the mount, in seconds. The mount mints one access token with this TTL and uses it until it expires; there is no refresh. Defaults to `3600` (1 hour). Maximum `86400` (24 hours). A value outside `1..86400` throws `InvalidOptionsError`.
</ParamField>

<ParamField path="cache.diskCache" type="{ path: string; maxSizeBytes?: number } | undefined">
  Optional on-disk cache. When omitted, the mount uses in-memory caching only.
</ParamField>

<ParamField path="telemetry.logLevel" type="'error' | 'warn' | 'info' | 'debug' | undefined">
  Minimum native log level. Defaults to `warn`.
</ParamField>

<ParamField path="telemetry.onLog" type="(record: LogRecord) => void | undefined">
  Per-instance structured log callback from the native filesystem.
</ParamField>

## RepoConfig

Pin a repository to a bookmark or change at mount time.

```ts theme={null}
const fs = await mesa.fs.mount({
  repos: [
    { name: 'app', bookmark: 'main' },
    { name: 'docs', changeId: 'zyxwvutsrqponmlkzyxwvutsrqponmlk' },
  ],
});
```

<ParamField path="RepoConfig.name" type="string" required>
  Repository name.
</ParamField>

<ParamField path="RepoConfig.bookmark" type="string | undefined">
  Bookmark to check out. Mutually exclusive with `changeId`.
</ParamField>

<ParamField path="RepoConfig.changeId" type="string | undefined">
  Change ID to check out. Mutually exclusive with `bookmark`.
</ParamField>

<ParamField path="RepoConfig.readOnly" type="boolean | undefined">
  When `true`, the mesa daemon rejects writes to this repo with `EROFS`, so a single mount can mix writable and read-only repos.
</ParamField>

## Disk cache

```ts theme={null}
const fs = await mesa.fs.mount({
  repos: [{ name: 'app' }],
  cache: { diskCache: { path: '/tmp/mesa-cache', maxSizeBytes: 500_000_000 } },
});
```

<ParamField path="cache.diskCache.path" type="string" required>
  Directory for the on-disk cache.
</ParamField>

<ParamField path="cache.diskCache.maxSizeBytes" type="number | undefined">
  Optional cache size cap. When omitted, the native extension auto-sizes the budget against system resources.
</ParamField>

## Paths

Mounted filesystem paths include the organization and repository name:

```text theme={null}
/<org>/<repo>/README.md
/acme/app/src/main.ts
```

## Response

Returns a `Promise<MesaFileSystem>`.

## MesaFileSystem

The returned `fs` object implements the `just-bash` filesystem interface and exposes async file I/O, metadata, traversal, mutation, Bash, and mounted-repo version-control helpers.

```ts theme={null}
await fs.mkdir('/acme/app/src', { recursive: true });
await fs.writeFile('/acme/app/src/main.ts', 'console.log("hello")\n');
const data = await fs.readFile('/acme/app/src/main.ts', 'utf8');
```

### Byte and text I/O

<ParamField path="readFile(path, options?)" type="Promise<string>">
  Read a file as text using a Node-compatible encoding. The `binary` encoding follows the `just-bash` latin1 byte-string convention.
</ParamField>

<ParamField path="readFileBuffer(path)" type="Promise<Uint8Array>">
  Read raw file bytes.
</ParamField>

<ParamField path="writeFile(path, content, options?)" type="Promise<void>">
  Replace file contents, creating the file if missing. Parent directories must already exist.
</ParamField>

<ParamField path="appendFile(path, content, options?)" type="Promise<void>">
  Append text or bytes to a file, creating it if missing.
</ParamField>

<ParamField path="exists(path)" type="Promise<boolean>">
  Return whether a path exists. Follows symlinks.
</ParamField>

### Metadata and traversal

<ParamField path="stat(path)" type="Promise<FsStat>">
  Return metadata for a path, following symlinks. `mtime` is a JavaScript `Date`.
</ParamField>

<ParamField path="lstat(path)" type="Promise<FsStat>">
  Return metadata for a path without following symlinks. `mtime` is a JavaScript `Date`.
</ParamField>

<ParamField path="readdir(path)" type="Promise<string[]>">
  Return entry names in a directory. Sort client-side if you need deterministic ordering.
</ParamField>

<ParamField path="readdirWithFileTypes(path)" type="Promise<Array<{ name: string; isFile: boolean; isDirectory: boolean; isSymbolicLink: boolean }>>">
  Return entry names with file type flags.
</ParamField>

<ParamField path="realpath(path)" type="Promise<string>">
  Resolve symlinks and `..` segments to a canonical path.
</ParamField>

<ParamField path="readlink(path)" type="Promise<string>">
  Return the target of a symlink.
</ParamField>

<ParamField path="resolvePath(base, path)" type="string">
  Join and normalize a path against a base path without touching the filesystem.
</ParamField>

<ParamField path="getAllPaths()" type="string[]">
  Return a synchronous snapshot of paths known to the filesystem.
</ParamField>

### Mutations

<ParamField path="mkdir(path, options?)" type="Promise<void>">
  Create a directory. With `{ recursive: true }`, create missing parents and do nothing when the path already exists as a directory.
</ParamField>

<ParamField path="rm(path, options?)" type="Promise<void>">
  Remove a file or directory. Use `{ recursive: true }` for non-empty directories and `{ force: true }` to ignore missing paths.
</ParamField>

<ParamField path="cp(src, dest, options?)" type="Promise<void>">
  Copy a file or directory. Use `{ recursive: true }` for directories.
</ParamField>

<ParamField path="mv(src, dest)" type="Promise<void>">
  Move or rename a file or directory.
</ParamField>

<ParamField path="chmod(path, mode)" type="Promise<void>">
  Set permission bits, such as `0o755`.
</ParamField>

<ParamField path="symlink(target, linkPath)" type="Promise<void>">
  Create a symlink. Relative targets are stored verbatim and resolve against the parent of `linkPath` at read time.
</ParamField>

<ParamField path="utimes(path, atime, mtime)" type="Promise<void>">
  Set access and modification times with JavaScript `Date` values.
</ParamField>

<ParamField path="link(existingPath, newPath)" type="Promise<void>">
  Create a hard link if supported by the native filesystem implementation.
</ParamField>

### Subscriptions

MesaFS reads and writes are realtime by default. Use subscriptions only when your process needs an event stream that identifies which paths changed, such as to refetch data and rerender a frontend.

<ParamField path="subscribe(handler)" type="MesaFileSystemSubscription">
  Subscribe to filesystem invalidation events. The handler is called after the changed state is visible through this filesystem instance.
</ParamField>

```ts theme={null}
const subscription = fs.subscribe(async (event) => {
  if (!event.recursive) {
    const content = await fs.readFile(event.path, 'utf8');
    console.log(event.path, content);
  }
});

subscription.unsubscribe();
```

<ParamField path="handler" type="(event: WatchEvent) => void | Promise<void>">
  Callback invoked for each filesystem invalidation.
</ParamField>

<ResponseField name="WatchEvent.path" type="string">
  Absolute MesaFS path that changed, such as `/acme/app/src/index.ts`.
</ResponseField>

<ResponseField name="WatchEvent.recursive" type="boolean">
  Whether descendants of `path` may have changed. Refresh any cached directory or subtree state below `path` when this is `true`.
</ResponseField>

<ResponseField name="MesaFileSystemSubscription.unsubscribe()" type="void">
  Stop receiving events and close the underlying watcher.
</ResponseField>

### FsStat

`stat(...)` and `lstat(...)` return `FsStat`.

<ResponseField name="isFile" type="boolean">
  Whether the path is a regular file.
</ResponseField>

<ResponseField name="isDirectory" type="boolean">
  Whether the path is a directory.
</ResponseField>

<ResponseField name="isSymbolicLink" type="boolean">
  Whether the path is a symlink. This is `false` from `stat(...)` when the target exists because `stat` follows symlinks.
</ResponseField>

<ResponseField name="mode" type="number">
  POSIX mode bits.
</ResponseField>

<ResponseField name="size" type="number">
  Size in bytes.
</ResponseField>

<ResponseField name="mtime" type="Date">
  Modification time.
</ResponseField>

### Related filesystem methods

| Method namespace    | Reference                                              |
| ------------------- | ------------------------------------------------------ |
| `fs.bash(...)`      | [fs.bash()](/content/reference/ts/fs-bash)             |
| `fs.change`         | [fs.change](/content/reference/ts/fs-changes)          |
| `fs.bookmark`       | [fs.bookmark](/content/reference/ts/fs-bookmarks)      |
| `fs.subscribe(...)` | [Advanced Realtime](/content/mesafs/advanced/realtime) |

## Errors

Throws `InvalidOptionsError` for an empty repo list or a `ttl` outside `1..86400`. Token signing or VCS connection failures can throw API errors or connection errors.
