> For the complete documentation index, see [llms.txt](/llms.txt).

# Connect to EVM - Node.js quickstart

Get started with MetaMask Connect EVM in a Node.js application. The SDK displays a QR code in the terminal that you scan with the MetaMask mobile app to establish a connection.

No polyfills required

Node.js has native support for `Buffer`, `crypto`, `stream`, and other modules that require polyfilling in browser or React Native environments.

## Prerequisites

- [Node.js](https://nodejs.org/) version 20 or later installed.
- A package manager installed, such as [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm), [Yarn](https://yarnpkg.com/), or [pnpm](https://pnpm.io/installation).
- The [MetaMask mobile app](https://metamask.io/download/) installed on your phone.
- An [Infura API key](https://docs.infura.io/dashboard/get-started/create-api) from the [Infura dashboard](https://app.infura.io).

## Steps

### 1. Install MetaMask Connect EVM

Install the EVM client in an existing Node.js project:

**npm**

```bash
npm install @metamask/connect-evm

```

**Yarn**

```bash
yarn add @metamask/connect-evm

```

**pnpm**

```bash
pnpm add @metamask/connect-evm

```

**Bun**

```bash
bun add @metamask/connect-evm

```

### 2. Initialize MetaMask Connect EVM

Create a file (`index.mjs`) and initialize the client using [createEVMClient](/metamask-connect/evm/reference/methods/#createevmclient). In Node.js, there is no `window.location`, so you must set `dapp.url` explicitly:

index.mjs

```javascript
import { createEVMClient, getInfuraRpcUrls } from '@metamask/connect-evm'

const evmClient = await createEVMClient({
  dapp: {
    name: 'My Node.js App',
    url: 'https://myapp.com',
  },
  api: {
    supportedNetworks: getInfuraRpcUrls({
      infuraApiKey: 'YOUR_INFURA_API_KEY',
    }),
  },
})

```

Async client

`createEVMClient` returns a promise. Always `await` it before using the client.

### 3. Connect to MetaMask

Call [connect](/metamask-connect/evm/reference/methods/#connect) to start the connection flow. A QR code appears in the terminal. Scan it with the MetaMask mobile app:

```javascript
try {
  const { accounts, chainId } = await evmClient.connect({
    chainIds: ['0x1'],
  })
  console.log('Connected account:', accounts[0])
  console.log('Active chain:', chainId)
} catch (error) {
  if (error.code === 4001) {
    console.log('User rejected the connection request')
  } else if (error.code === -32002) {
    console.log('Connection request already pending')
  } else {
    console.error('Connection failed:', error)
  }
}

```

### 4. Use the provider

Get the EIP-1193 provider and make JSON-RPC requests:

```javascript
const provider = evmClient.getProvider()

const balance = await provider.request({
  method: 'eth_getBalance',
  params: [accounts[0], 'latest'],
})
console.log('Balance (wei):', balance)

```

### 5. Sign a message

Use [personal_sign](/metamask-connect/evm/reference/json-rpc-api/personal%5Fsign/) to request a signature from the connected wallet:

```javascript
const message = '0x' + Buffer.from('Hello from Node.js!', 'utf8').toString('hex')

const signature = await provider.request({
  method: 'personal_sign',
  params: [message, accounts[0]],
})
console.log('Signature:', signature)

```

### 6. Disconnect

```javascript
await evmClient.disconnect()
console.log('Disconnected')

```

## Listen for events

Use `eventHandlers` in the client configuration to react to connection state changes:

```javascript
const evmClient = await createEVMClient({
  dapp: {
    name: 'My Node.js App',
    url: 'https://myapp.com',
  },
  api: {
    supportedNetworks: getInfuraRpcUrls({
      infuraApiKey: 'YOUR_INFURA_API_KEY',
    }),
  },
  eventHandlers: {
    connect: ({ accounts, chainId }) => {
      console.log('Connected:', accounts, 'on chain', chainId)
    },
    disconnect: () => {
      console.log('Disconnected')
    },
    accountsChanged: accounts => {
      console.log('Accounts changed:', accounts)
    },
    chainChanged: chainId => {
      console.log('Chain changed:', chainId)
    },
  },
})

```

## Full example

index.mjs

```javascript
import { createEVMClient, getInfuraRpcUrls } from '@metamask/connect-evm'

const evmClient = await createEVMClient({
  dapp: {
    name: 'My Node.js App',
    url: 'https://myapp.com',
  },
  api: {
    supportedNetworks: getInfuraRpcUrls({
      infuraApiKey: 'YOUR_INFURA_API_KEY',
    }),
  },
})

// Connect — scan the QR code with the MetaMask mobile app
const { accounts, chainId } = await evmClient.connect({ chainIds: ['0x1'] })
console.log('Connected:', accounts[0], 'on', chainId)

// Get balance
const provider = evmClient.getProvider()
const balance = await provider.request({
  method: 'eth_getBalance',
  params: [accounts[0], 'latest'],
})
console.log('Balance:', balance)

// Sign a message
const message = '0x' + Buffer.from('Hello from Node.js!', 'utf8').toString('hex')
const signature = await provider.request({
  method: 'personal_sign',
  params: [message, accounts[0]],
})
console.log('Signature:', signature)

// Disconnect
await evmClient.disconnect()
console.log('Disconnected')

```

Run it with:

```bash
node index.mjs

```

## Next steps

- [Manage user accounts](/metamask-connect/evm/guides/manage-user-accounts/)
- [Send transactions](/metamask-connect/evm/guides/send-transactions/)
- [Sign data](/metamask-connect/evm/guides/sign-data/)
