MetaMask - SvelteKit - Web3 - Blockchain - Tutorial

MetaMask Connection in SvelteKit

Web3 Tutorial: In-Depth Guide to MetaMask Connection in Svelte


In today’s blog post, we’re diving deeper into the integration of MetaMask with a SvelteKit application. This guide complements our quick YouTube tutorial by offering a more detailed explanation. We’ll go through the steps of setting up the SvelteKit project, creating custom Svelte stores, and the mechanics of connecting MetaMask to your application.

Why SvelteKit and Svelte Stores?

First off, why SvelteKit? SvelteKit provides an all-in-one framework with essential features like routing, server-side rendering, and a great development experience. For Web3 applications that often require complex states and reactivity, this is invaluable.

As for Svelte Stores, they provide a simple yet powerful state management system. Stores in Svelte allow you to share reactive values across components, making them ideal for managing the state of our MetaMask connection.

Step 1: The Foundation—SvelteKit and Custom Store

The full repo for this tutorial is available on GitHub if you want to follow along.

Create a New SvelteKit Project

To start, create a new SvelteKit project by running the command:

npm init svelte@next

Set Up a Custom Store

Navigate to src/lib/ and create a new file named index.js. Here, we will define our custom store.

First, import the writable function from Svelte’s store package:

import { writable } from "svelte/store";

This function allows us to create a writable store that we can both update and subscribe to.

Step 2: MetaMask Checks and Connect Button

Checking for MetaMask

We define a utility function called getMetaMaskPresent() that checks if the MetaMask extension is installed in the browser. This function checks for the presence of the global window.ethereum object.

const getMetaMaskPresent = () =>
  typeof window !== "undefined" && typeof window.ethereum !== "undefined";

Writable Stores

We use three writable stores:

  1. loaded - To track if the client-side application has loaded. This is crucial because MetaMask can only be accessed client-side.
  2. isMetaMaskPresent - To store the Boolean value returned by getMetaMaskPresent().
  3. walletState - To manage the state of the MetaMask wallet, like the address or the current network.
const loaded = writable(false);
const isMetaMaskPresent = writable(getMetaMaskPresent());
const walletState = writable(getLocalStorageState());

Connecting to MetaMask

The connect function is responsible for sending a eth_requestAccounts request to MetaMask. This is an Ethereum JSON-RPC method that prompts the user to connect their wallet to your app.

const connect = async () => {
  if (!getMetaMaskPresent()) {
  const accountResponse = await window.ethereum?.request({
    method: "eth_requestAccounts",
  // ...

Step 3: Initialization and Persistence

The init Function

The init function serves a dual purpose:

  1. It checks if the user has previously connected MetaMask to the app. This is done by checking the local storage.
  2. It also registers an event listener that fires when there’s a change in the wallet state (like account switching or disconnection).

Subscribing to Wallet State Changes

We use Svelte’s .subscribe method to track any changes to our walletState. Whenever it changes, we update the local storage:

walletState.subscribe((state) => {
  if (typeof window !== "undefined") {
    window.localStorage.setItem("walletState", JSON.stringify(state));

This ensures that the next time the user visits the app, they won’t have to reconnect their wallet, making for a much smoother user experience.


By leveraging SvelteKit’s built-in functionalities and Svelte’s simple state management, we can efficiently build a MetaMask-connected application. The key here is the careful setup of custom stores and utility functions to manage the wallet’s state and interactions with the MetaMask extension.

You can find the complete code in the description or on my blog. And if you haven’t already, check out the quick video tutorial that covers this topic in less than 3 minutes.

For those who are more into reading, I hope this post provided the in-depth details you were looking for. As always, feel free to comment, like, or subscribe. See you in the next tutorial!