# @metamask/snaps-cli

> A CLI for developing MetaMask Snaps

Latest version **8.4.1** (published 2026-03-06) · ISC license · 0 weekly downloads

## Install

```sh
npm install @metamask/snaps-cli
pnpm add @metamask/snaps-cli
yarn add @metamask/snaps-cli
bun add @metamask/snaps-cli
```

Provides the command `mm-snap`.

## Health

**Score 65/100 (B)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 8.4.1 |
| Published | 2026-03-06 |
| First published | 2021-09-09 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | ^20 \|\| >=22 |
| Dependencies | 43 |
| Unpacked size | 775 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 858 |
| Maintainers | danfinlay, kumavis, metamaskbot, gudahtt |
| Keywords | MetaMask, Snaps, Ethereum |

## Links

- npm: https://www.npmjs.com/package/@metamask/snaps-cli
- Repository: https://github.com/MetaMask/snaps
- Homepage: https://github.com/MetaMask/snaps/tree/main/packages/snaps-cli#readme
- Issues: https://github.com/MetaMask/snaps/issues
- npm.io page: https://npm.io/package/@metamask/snaps-cli

## Dependencies (43)

- [ora](https://npm.io/package/ora.md) ^5.4.1
- [url](https://npm.io/package/url.md) ^0.11.1
- [util](https://npm.io/package/util.md) ^0.12.5
- [chalk](https://npm.io/package/chalk.md) ^4.1.2
- [yargs](https://npm.io/package/yargs.md) ^17.7.1
- [assert](https://npm.io/package/assert.md) ^2.0.0
- [buffer](https://npm.io/package/buffer.md) ^6.0.3
- [events](https://npm.io/package/events.md) ^3.3.0
- [semver](https://npm.io/package/semver.md) ^7.5.4
- [express](https://npm.io/package/express.md) ^5.1.0
- [process](https://npm.io/package/process.md) ^0.11.10
- [webpack](https://npm.io/package/webpack.md) ^5.97.1
- [punycode](https://npm.io/package/punycode.md) ^2.3.0
- [@swc/core](https://npm.io/package/@swc/core.md) 1.11.31
- [strip-ansi](https://npm.io/package/strip-ansi.md) ^6.0.1
- [swc-loader](https://npm.io/package/swc-loader.md) ^0.2.6
- [stream-http](https://npm.io/package/stream-http.md) ^3.2.0
- [os-browserify](https://npm.io/package/os-browserify.md) ^0.3.0
- [vm-browserify](https://npm.io/package/vm-browserify.md) ^1.1.2
- [webpack-merge](https://npm.io/package/webpack-merge.md) ^5.9.0
- [domain-browser](https://npm.io/package/domain-browser.md) ^4.22.0
- [string_decoder](https://npm.io/package/string_decoder.md) ^1.3.0
- [tty-browserify](https://npm.io/package/tty-browserify.md) ^0.0.1
- [@metamask/utils](https://npm.io/package/@metamask/utils.md) ^11.10.0
- [browserify-zlib](https://npm.io/package/browserify-zlib.md) ^0.2.0
- [path-browserify](https://npm.io/package/path-browserify.md) ^1.0.1
- [querystring-es3](https://npm.io/package/querystring-es3.md) ^0.2.1
- [readable-stream](https://npm.io/package/readable-stream.md) ^3.6.2
- [https-browserify](https://npm.io/package/https-browserify.md) ^1.0.0
- [crypto-browserify](https://npm.io/package/crypto-browserify.md) ^3.12.0
- [stream-browserify](https://npm.io/package/stream-browserify.md) ^3.0.0
- [timers-browserify](https://npm.io/package/timers-browserify.md) ^2.0.12
- [console-browserify](https://npm.io/package/console-browserify.md) ^1.2.0
- [@metamask/snaps-sdk](https://npm.io/package/@metamask/snaps-sdk.md) ^10.4.0
- [constants-browserify](https://npm.io/package/constants-browserify.md) ^1.0.0
- [@metamask/snaps-utils](https://npm.io/package/@metamask/snaps-utils.md) ^12.1.0
- [@metamask/superstruct](https://npm.io/package/@metamask/superstruct.md) ^3.2.1
- [terser-webpack-plugin](https://npm.io/package/terser-webpack-plugin.md) ^5.3.9
- [@metamask/snaps-sandbox](https://npm.io/package/@metamask/snaps-sandbox.md) ^1.0.1
- [webpack-bundle-analyzer](https://npm.io/package/webpack-bundle-analyzer.md) ^4.10.2
- [@metamask/snaps-rpc-methods](https://npm.io/package/@metamask/snaps-rpc-methods.md) ^14.3.0
- [@metamask/snaps-webpack-plugin](https://npm.io/package/@metamask/snaps-webpack-plugin.md) ^5.1.2
- [fork-ts-checker-webpack-plugin](https://npm.io/package/fork-ts-checker-webpack-plugin.md) ^9.0.2

## Recent versions

- 8.4.1 (latest) — 2026-03-06
- 0.38.4-flask.1 (flask) — 2023-09-20
- 1.0.0-prerelease.1 (next) — 2023-06-23
- 0.32.2 (dev) — 2023-03-30
- 8.4.0 — 2026-01-22
- 8.3.0 — 2025-08-20
- 8.2.0 — 2025-08-06
- 8.1.1 — 2025-07-09
- 8.1.0 — 2025-06-27
- 8.0.0 — 2025-06-10
- 7.2.0 — 2025-05-27
- 7.1.0 — 2025-04-23
- 7.0.0 — 2025-04-16
- 6.7.0 — 2025-02-11
- 6.6.1 — 2025-01-14
- … 107 more at https://npm.io/package/@metamask/snaps-cli/versions

## README

# @metamask/snaps-cli

A CLI for developing MetaMask Snaps.

## Installation

Use Node.js `18.16.0` or later.
We recommend [nvm](https://github.com/nvm-sh/nvm) for managing Node.js versions.

Install a dev dependency in your snap project using `yarn` or `npm`:

- `npm install --save-dev @metamask/snaps-cli`
- `yarn add -D @metamask/snaps-cli`

## Usage

```text
Usage: mm-snap <command> [options]

Commands:
  mm-snap build     Build snap from source                          [aliases: b]
  mm-snap eval      Attempt to evaluate snap bundle in SES          [aliases: e]
  mm-snap manifest  Validate the snap.manifest.json file            [aliases: m]
  mm-snap sandbox   Start a sandbox server to interact with the Snap
  mm-snap serve     Locally serve Snap file(s) for testing          [aliases: s]
  mm-snap watch     Build Snap on change                            [aliases: w]

Options:
      --version  Show version number                                   [boolean]
  -c, --config   Path to config file                                    [string]
  -h, --help     Show help                                             [boolean]

Examples:
  mm-snap build                             Build './src/index.js' as './dist/bu
                                            ndle.js'
  mm-snap build --config ./snap.config.bui  Build './src/index.js' as './dist/bu
  ld.ts                                     ndle.js' using the config in './snap
                                            .config.build.ts'
  mm-snap manifest --fix                    Check the snap manifest, and fix any
                                             errors
  mm-snap watch --port 8000                 The snap input file for changes, and
                                             serve it on port 8000
  mm-snap serve --port 8000                 Serve the snap bundle on port 8000
```

## MetaMask Snaps

MetaMask Snaps enables trustlessly extending the functionality of MetaMask at
runtime. A snap consist of two things: a JSON manifest and a JavaScript bundle.
At present, snaps can be published as npm packages on the public npm registry,
or hosted locally during development. In the future, it will be possible to
publish snaps on many different platforms, including arbitrary npm registries
and IPFS.

We recommend building your snap using this tool. You can bundle your snap using
your own tools, but it must run in SES and only use the global APIs that
MetaMask exposes at runtime. Although snaps currently execute in the browser,
some browser APIs are not available to snaps, and snaps do not have DOM access.

### The Snap Manifest

Your manifest must be named `snap.manifest.json` and located in the root
directory of your npm package. Here's an example manifest:

```json
{
  "version": "0.7.0",
  "proposedName": "Dialog Example",
  "description": "A MetaMask Snap template.",
  "repository": {
    "type": "git",
    "url": "https://github.com/MetaMask/template-snap.git"
  },
  "source": {
    "shasum": "w3FltkDjKQZiPwM+AThnmypt0OFF7hj4ycg/kxxv+nU=",
    "location": {
      "npm": {
        "filePath": "dist/bundle.js",
        "iconPath": "images/icon.svg",
        "packageName": "@metamask/template-snap",
        "registry": "https://registry.npmjs.org/"
      }
    }
  },
  "initialPermissions": {
    "snap_dialog": {},
    "endowment:rpc": {
      "dapps": true,
      "snaps": false
    }
  },
  "manifestVersion": "0.1"
}
```

Refer to [the Snaps publishing specification](https://github.com/MetaMask/specifications/blob/main/snaps/publishing.md)
for more information about the manifest.

> **Note**: If your snap is not compatible with the publishing specification,
> your snap may not work properly or install at all.

### Assumed Project Structure

This tool has default arguments assuming the following project structure:

```text
snap-project/
├─ package.json
├─ src/
│  ├─ index.js
├─ snap.manifest.json
├─ dist/
│  ├─ bundle.js
├─ ... (all other project files and folders)
```

Source files other than `index.js` are located through its imports. The
defaults can be overwritten using the `snap.config.js` or (`snap.config.ts`)
[config file](#configuration).

## Configuration

The MetaMask Snaps CLI supports a configuration file. It can be either:

- `snap.config.js` - a CommonJS module.
- `snap.config.ts` - a TypeScript module.

The file should be placed in the project root directory.

### Example

#### JavaScript

```javascript
module.exports = {
  input: 'src/index.js',
  output: {
    path: 'dist',
  },
  server: {
    port: 9000,
  },
};
```

#### TypeScript

The CLI has full support for TypeScript out of the box. `@metamask/snaps-cli`
exports a `SnapConfig` type that can be used to type the configuration object.

```typescript
import type { SnapConfig } from '@metamask/snaps-cli';

const config: SnapConfig = {
  input: 'src/index.js',
  output: {
    path: 'dist',
  },
  server: {
    port: 9000,
  },
};

export default config;
```

The configuration file should not be published.

### Options

- [`input`](#input)
- [`output`](#output)
  - [`output.path`](#outputpath)
  - [`output.filename`](#outputfilename)
  - [`output.clean`](#outputclean)
  - [`output.minimize`](#outputminimize)
- [`server`](#server)
  - [`server.enabled`](#serverenabled)
  - [`server.root`](#serverroot)
  - [`server.port`](#serverport)
- [`environment`](#environment)
- [`stats`](#stats)
  - [`stats.verbose`](#statsverbose)
  - [`stats.builtIns`](#statsbuiltins)
  - [`stats.buffer`](#statsbuffer)
- [`customizeWebpackConfig`](#customizewebpackconfig)
- [`experimental`](#experimental)
  - [`experimental.wasm`](#experimentalwasm)

#### `input`

- Type: `string`
- Default: `"src/index.js"`

The entry point of your snap. This is the file that will be bundled.

#### `output`

- Type: `object`

The output configuration.

##### `output.path`

- Type: `string`
- Default: `"dist"`

The output directory.

##### `output.filename`

- Type: `string`
- Default: `"bundle.js"`

The output filename.

##### `output.clean`

- Type: `boolean`
- Default: `false`

Whether to clean the output directory before building.

##### `output.minimize`

- Type: `boolean`
- Default: `true`

Whether to minimize the bundle. This will remove comments and whitespace from
the bundle, mangle variable names, and perform other optimizations.

#### `sourceMap`

- Type: `boolean | "inline"`
- Default: `true`

Whether to generate a source map. If `"inline"`, the source map will be
inlined in the bundle. Otherwise, it will be written to a separate file.

#### `evaluate`

- Type: `boolean`

Whether to evaluate the bundle. This will check the bundle for compatibility
issues with the MetaMask Snaps runtime. If there are any issues, the CLI will
exit with an error.

#### `manifest`

- Type: `object`

The snap manifest configuration.

##### `manifest.path`

- Type: `string`
- Default: `"snap.manifest.json"`

The path to the snap manifest, i.e., `snap.manifest.json`.

##### `manifest.update`

- Type: `boolean`
- Default: `true`

Whether to update the manifest with the bundle shasum, and any other possible
updates. If `false`, the manifest will not be updated, and an error will be
thrown if the manifest is not up-to-date.

#### `server`

- Type: `object`

The development server configuration. The development server is used to test
your snap during development, using the `watch` and `serve` commands.

##### `server.enabled`

- Type: `boolean`
- Default: `true`

Whether to enable the development server. If `false`, the development server
will not be started when running the `watch` command. This option has no effect
on the `serve` command.

##### `server.root`

- Type: `string`
- Default: `process.cwd()`

The root directory of the development server. This is the directory that will
be served by the development server.

##### `server.port`

- Type: `number`
- Default: `8081`

The port to run the development server on. If set to `0`, a random port will
be used.

#### `environment`

- Type: `Record<string, unknown>`

The environment configuration. This is used to set environment variables for
the snap, which can be accessed using `process.env`.

In addition to the environment variables set by the user, the following
environment variables are set by the CLI:

- `NODE_ENV` - `"production"`.
- `NODE_DEBUG` - `false`.
- `DEBUG` - `false`.

#### `stats`

- Type: `object`

The stats configuration, which controls the log output of the CLI.

##### `stats.verbose`

- Type: `boolean`
- Default: `false`

Whether to enable verbose logging. If `true`, the CLI will log more
information.

##### `stats.builtIns`

- Type: `false | object`
- Default: `{ ignore: [] }`

Whether to check for missing built-in modules. The MetaMask Snaps CLI does not
support Node.js built-ins out of the box, and any used built-ins must be
provided through the `customizeWebpackConfig` option. When enabled, the CLI
shows a warning if a built-in module is used, but not provided.

###### `stats.builtIns.ignore`

- Type: `string[]`

A list of built-in modules to ignore. This is useful if the built-in module is
not actually used in the snap, but is added by a dependency.

###### `stats.buffer`

- Type: `boolean`
- Default: `true`

Whether to show a warning if `Buffer` is used, but not provided. The `Buffer`
global is not available in the MetaMask Snaps runtime by default, and must
be provided through the `customizeWebpackConfig` option.

#### `customizeWebpackConfig`

- Type: `(config: webpack.Configuration) => webpack.Configuration`

A function that can be used to customize the Webpack configuration. This is
useful if you need to add a Webpack plugin, provide a polyfill, add a loader,
and so on.

The function receives the Webpack configuration object, and should return the
modified configuration object. For convenience, `@metamask/snaps-cli` exports
a `merge` function (re-exported from `webpack-merge`) that can be used to merge
the configuration object with the default configuration.

The default configuration can be found in [`src/webpack/config.ts`](./src/webpack/config.ts).

```typescript
import type { SnapConfig } from '@metamask/snaps-cli';
import { merge } from '@metamask/snaps-cli';

const config: SnapConfig = {
  customizeWebpackConfig: (config) =>
    merge(config, {
      plugins: [
        // Add a plugin.
      ],
      module: {
        rules: [
          // Add a loader.
        ],
      },
    }),
};

export default config;
```

#### `experimental`

- Type: `object`

Experimental features. These features are not stable, and may change in the
future.

##### `experimental.wasm`

- Type: `boolean`

Whether to enable WebAssembly support. When this is enabled, WebAssembly files
can be imported in the snap, for example:

```typescript
import program from './program.wasm';

// Program is initialised synchronously.
// ...
```

---
_Source: https://npm.io/package/@metamask/snaps-cli · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
