Building Web3 Dapps with Svelte
| Published: January 17, 2024
| Updated: January 19, 2024
Since web3 became viable and Ethereum gained meaningful adoption, React has been used to create almost all popular decentralized applications (‘dapps’). This is mainly due to the fact that until now, React has been the only clear choice for front-end developers, therefore all web3 tooling was built for React.
Coming into 2024, web3 is steadily gaining it’s momentum again, and the web-dev space is in a very different place than last time it such popularity. Developers are moving to Svelte/SvelteKit in droves, and are leaving React and Next.js behind.
So, where does that leave the existing web3 libraries? Thankfully most of the popular libraries are built around a vanilla Javascript core, so porting over to SvelteKit is trivial.
But in 2024, it’s clear more dapps are going to be built with Svelte than any year before. So as a new web3 season begins, it’s time to re-evaluate how to best build decentralized applications. And with SvelteKit now on the menu, I’m going to run through the tooling available. I’m also going to give opinions about how I best believe you can make dapps with SvelteKit.
So let’s look at the tools you should use to handle at least 95% of your dapp’s functionality.
SvelteKit tools for Web3 Dapps
These are the main libraries you should know when creating a dapp:
If you look at each of them, you would’ve noticed the lack of ‘Svelte’, and even a focus on using with React with Wagmi and Moralis. But we’re not building with React.
Whilst there’s no official support for Svelte, they all have a ‘Vanilla Javascript’ core, so building Svelte-specific integrations and stores is simple. And unofficial Svelte ports already exist.
Before we start, let’s sort out our RPC connections
Before we look at these tools, you’ll need to have an RPC service to connect to a blockchain. An RPC is just a key provided to you to access their ‘node’ on a blockchain, so that you can read and write data to the blockchain from your dapp.
The two main services for RPC connections are Alchemy and Infura (both are free). Moralis has their own RPC connection built into the SDK when you initialize your app, however the other standalone libraries require you provide some RPC string.
ethers.js and web3.js
These are the two primitives for building web3 applications. Most of the web3 technologies are built on top of one of these libraries. They are big libraries with all the functionality you could ever want or need.
With that said, they aren’t the best solutions if you want a good developer experience. The provide the ingredients, but you still have to make the recipe and cook the food!
The docs for both of these libraries are fairly complicated and dry, so new developers might find using these libraries intimidating.
However, if you’re more experienced and want to be as lightweight as possible or learn how the pieces move, using either of these on their own is a good idea.
Feel free to check out their docs here:
Using ethers.js or web3.js with Svelte
There’s even some Svelte-based library for ethers.js and a svelte-based option for web3.js, which provide readable stores to help perform common tasks in Svelte, such as:
- Connect to wallet,
- Monitor user connection status,
- Monitor Chain ID user wallet is connected to (e.g. Ethereum Mainnet, or Sepolia Testnet etc.),
- Check user balance etc.
But if you want the best developer experience where things ‘just work’ without getting too into the weeds, then look towards the following options.
Wagmi
Wagmi is an incredibly popular library, which is built on top of ethers.js. Wagmi’s main value prop is that it uses the ethers.js library to make simple API’s which provide meaningful data that is used in most dapps.
It’s an open-source library with no vendor lock-in and the ability to customize it with any of your providers or chains, provided they are EVM (Ethereum Virtual Machine) based. This just means they connect with protocols based on the original Ethereum protocol.
It has utility functions for all the processes you’ll need to build a dapp, plus some nice functions to improve UX that aren’t implemented in any of the other web3 libraries. An example of this is the prepareWriteContract
function, where the library will simulate you transaction to present you a mock of the transaction, returning expected gas fees, and outputs etc.
That is why I would most commonly recommend developers build with Wagmi when creating their dapp.
The only problem is that there is no official Svelte version for Wagmi.
Using wagmi with Svelte
There is a great unofficial library called svelte-wagmi which I’ve used for dapps, and it works better than anything I’ve used before. With access to Svelte Readable stores, svelte-wagmi is arguably more developer-friendly than its ‘official’ React alternative.
It even has a built-in instance of the WalletConnect Web3Modal which takes away a lot of the unnecessary complexity of connecting your wallet to the dapp.
So if you need to connect, simply import $web3Modal
from svelte-wagmi
and then call the openModal()
method.
import { web3Modal } from 'svelte-wagmi';
$web3Modal.openModal();
Then you have a nicely styled modal appear, where you can connect with most types of wallets, including a mobile.
And once you click your type of wallet, and Accept the request with your wallet, you’re logged in and everything is integrated with wagmi, and you have the tools to build a chain-agnostic dapp.
It’s super simple, and it’s reactive, so any changes made with your wallet (e.g. changing chains, or balances etc.) reflect instantly in your dapp.
If you struggle to make your app connect, remember that you need to initialize your dapp in you main +layout.svelte
file:
<script lang='ts'>
import { defaultConfig } from 'svelte-wagmi';
import { onMount } from 'svelte';
import { PUBLIC_WALLETCONNECT_ID, PUBLIC_ALCHEMY_ID } from '$env/static/public';
onMount(async () => {
const erckit = defaultConfig({
appName: 'App Name',
walletConnectProjectId: PUBLIC_WALLETCONNECT_KEY,
alchemyId: PUBLIC_ALCHEMY_KEY
});
await erckit.init();
});
</script>
Before accessing any of the functionality, you should initialize (or connect) to your RPC provider.
Moralis
Moralis goes a step above Wagmi, and provides more useful utility functions, like getWalletTokenBalances()
:
const response = await Moralis.EvmApi.token.getWalletTokenBalances({
address,
chain
});
or getWalletNFTs()
:
const response = await Moralis.EvmApi.nft.getWalletNFTs({
address,
chain
});
Whilst you can technically do many of these actions with the other libraries mentioned above, you usually have to consult an RPC service which indexes all blockchain events and is able to perform these data fetches.
For example, Alchemy can get this rich data from the blockchain with their SDK, however it’s often better to centralize your services to as few as possible, so that when problems arise it should be more simple to debug.
Moralis is more batteries included than any of the other libraries on this list - it provides the data layer and also the SDK which allows you to call blockchain action from your dapp.
The core Moralis library is open source, however you need to initialize it with a Moralis API key to do anything with the SDK.
It’s worth noting that Moralis also has several API’s, specifically tailored to multiple chains (including non-EVM’s) or niches, such as a metaverse SDK.
You can check out the Moralis docs here.
Using Moralis with Svelte
There’s no official Svelte integration for Moralis, nor is there a useful unofficial port. However, the core Moralis library is built with plain Javascript, so you can get Moralis working in Svelte by doing the following:
Firstly, there are issues using the Moralis Library with npm, so the it’s best to import it in your src/app.html
file:
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
<script src="https://unpkg.com/moralis/dist/moralis.js"></script>
And then initialize it from you main +layout.svelte
file:
<script lang='ts'>
import { onMount } from 'svelte';
let moralisStarted = false;
function configureMoralis() {
const serverUrl = import.meta.env.VITE_PUBLIC_MORALIS_SERVER_URL;
const appId = import.meta.env.VITE_PUBLIC_MORALIS_APP_ID;
Moralis.start({ serverUrl, appId });
moralisStarted = true;
}
onMount(() => {
configureMoralis();
});
</script>
So, with this in mind, Moralis is a great option for getting rich data into your apps quickly, but for a production-level app that gets used by people, I’d rather select Wagmi.
When to choose each library
We have detailed each of the leading libraries you should use to build your dapp with in Svelte, so now let’s go through each of the scenarios for when you should use each library.
🏆 svelte-wagmi - General Ethereum-Based Dapps
The svelte-wagmi library is the library I reach for 9 times out of 10 when I need to build a dapp. It has powerful and reliable stores, and I can get the primitives of a dapp up and running in less than 10 minutes.
It also has intuitive approaches to interacting with smart contracts, and the native integration with web3Modal makes it hard to pass on.
The only downside to this library is that it is entirely EVM based, meaning you can only use it for blockchains which are based on the Ethereum protocol. The main EVM public chains you can use wagmi and svelte-wagmi for are:
- Ethereum,
- Binance Smart Chain,
- Pulsechain,
- Avalanche,
- Polygon,
- Optimism,
- Arbitrum,
- Fantom,
- Klaytn,
- etc.
There are other EVM based chains, but if you’re not building on one of these chains, it’s likely you’re not using an EVM. In which case, this library won’t work for you, so I’d recommend the next option.
🏆 Moralis - Quick MVP/prototyping or Non-EVM development
The Moralis library has SDK’s for Ethereum-based chains, Aptos and Solana. If you’re developing a dapp for Aptos and Solana, I’d recommend the Moralis SDK.
Moralis is also a freemium product, which means prices can get high quickly when you gain significant inflow of users. However, if you need to get rich data into your dapp, there’s no faster way than Moralis.
🏆 ethers.js - Flexibility and Minimum Bundle Size
If you don’t want to use an abstracted library like wagmi or Moralis, you’re still going to need a library which relieves from going into coo-koo land. Without getting too esoteric, you should at least employ a library to provide basic abstractions like ethers.js or web3.js. Without this, you’ll have a bad time connecting to and interacting with blockchain RPC’s.
The ethers.js library is the longest standing and most widely used library to build decentralized applications (explicitly or by library inheritance). It is flexible and powerful, however performing simple tasks like monitoring your wallet’s connection status can be overly verbose.
Beyond your dapp
If you’re building a dapp which performs some additional logic on-chain to what is already existing, you’ll probably need to create and deploy smart contracts.
The contract creation and deploy process will be entirely separate from your SvelteKit dapp, however you will interract with them from your dapp.
For example:
- If you wanted to create a front-end for the Uniswap decentralized exchange where you access the current liquidity on-chain, you can do that using the tools mentioned in this article.
- But if you wanted to clone a completely fresh instance of a Uniswap clone with no liquidity, then you would need to deploy the contracts on-chain yourself. And for that, you need more than the tools mentioned in this article.
Performing this is outside the scope of this article, however there are some tools and things you’ll need to know before doing this:
- You’ll need to know the Solidity programming language if you plan on making or modifying existing smart contracts,
- Use a tool like Remix, Foundry or Hardhat to compile, run tests and deploy smart contracts
- Remix is an online IDE with a tonne of tooling to make this stage as simple as possible. It also has plugins to perform tasks like verifying contracts in Etherscan with a click of a button.
- Foundry is a CLI which is fast and runs multiple types of tests, which are written in Solidity.
- Hardhat is also a CLI which has fewer features then Foundry, however it is Javascript-based.
🏆 Remix - Deploying Smart Contracts without Testing
Generally, if you’re a beginner to Solidity or don’t care so much about this part of developing: learn the Solidity basics and deploy in Remix.
The interface and user experience make this super easy to do things that are generally complex under the hood. The only downsides with Remix are:
- you aren’t working in your own IDE, although you can sync Remix with your local file system using Remixd
- you don’t have the level of testing that you get in Foundry or Hardhat, although there is a unit testing plugin here
- you can’t run complex scenarios with chain cloning
But this is a brilliant tool which hides away a lot of the complexity in the CLI tools.
🏆 Foundry - Deploying Smart Contracts with Testing
If you want to become proficient dealing with smart contract development, I’d recommend you: Learn Solidity and start developing in Foundry.
Foundry is not as easy to use as Remix starting out, but you get access to a bunch of testing features that any serious Solidity developer should use, like temporary chain cloning, fuzz testing and unit tests. It’s also significantly faster than Hardhat. This is important, because you’ll be doing this a lot!
Conclusion
Web3 is once again gaining serious adoption, and it’s best to be ahead of the curve. We know the Svelte ecosystem is behind the 8-ball for web3 tooling, however if React isn’t your style, there are great Svelte ports for most of the popular libraries. And with the addition of native readable stores in Svelte, using web3 auth superior compared to most other frameworks.
For Svelte, we generally recommend svelte-wagmi, however if you need to build for non-EVM chains, then Moralis is the way to go.
And if you need to create and deploy smart contracts for your dapp, it’s worth learning Solidity and how to use the Remix IDE. However, if you want to be a more proficient smart contract developer, you should use Foundry for all the tooling the pro’s use.
Good luck with your dapp!