Mesh LogoMesh
ResourcesChallenges

Cardano Development Challenges

Overcome common Cardano dApp development challenges. Learn how Mesh SDK solves UTXO complexity, wallet integration, and transaction failures.

Cardano development presents unique challenges due to the extended UTXO model. This guide covers the five most common obstacles you encounter when building dApps, and shows how Mesh solves each one.

The challenge

Cardano uses the UTXO (Unspent Transaction Output) model instead of Ethereum's account model. Your balance consists of discrete outputs that you must explicitly select and consume. This architectural difference creates several challenges:

AspectEthereumCardano
BalanceSingle number per addressSum of discrete UTXOs
TransactionsModify account stateConsume and create UTXOs
ConcurrencySimple state updatesRequires UTXO coordination
Smart contractsEVM with gasPlutus/Aiken with execution budgets

Common challenges at a glance

ChallengeRoot causeMesh solution
Transaction failuresUTXO selection, fee calculationAutomatic handling in MeshTxBuilder
UTXO complexityDiscrete outputs instead of balancesselectUtxosFrom() abstracts selection
Wallet fragmentationMany small change outputsOptimized coin selection algorithms
Fee calculationCircular dependency on tx sizeIterative calculation in complete()
Smart contract integrationDatums, redeemers, execution budgetsHigh-level APIs for script interaction

Explore specific challenges

Quick start

Get started in four steps.

Step 1: Install Mesh

npm install @meshsdk/core @meshsdk/react

Step 2: Configure a provider

import { BlockfrostProvider } from "@meshsdk/core";

const provider = new BlockfrostProvider("<your-api-key>");

Step 3: Connect a wallet

import { MeshCardanoBrowserWallet } from "@meshsdk/wallet";

const wallet = await MeshCardanoBrowserWallet.enable("eternl");

Step 4: Build and submit a transaction

import { MeshTxBuilder } from "@meshsdk/core";

const txBuilder = new MeshTxBuilder({
  fetcher: provider,
  submitter: provider,
});

const unsignedTx = await txBuilder
  .txOut(recipientAddress, [{ unit: "lovelace", quantity: "5000000" }])
  .changeAddress(await wallet.getChangeAddressBech32())
  .selectUtxosFrom(await wallet.getUtxosMesh())
  .complete();

const signedTx = await wallet.signTx(unsignedTx, false);
const txHash = await wallet.submitTx(signedTx);

Best practices

Follow these practices to avoid common pitfalls:

  • Fetch fresh UTXOs before building transactions to avoid conflicts
  • Use automatic UTXO selection instead of manual input management
  • Handle errors gracefully with user-friendly messages
  • Test on preprod before deploying to mainnet
  • Use TypeScript for compile-time error detection

Why Mesh

FeatureBenefit
TypeScript-firstType safety and IDE support
Automatic UTXO managementNo manual coin selection
Framework-agnosticWorks with React, Svelte, Next.js, Node.js
Multiple providersBlockfrost, Koios, Maestro, Ogmios
Active maintenanceRegular updates for Cardano changes
ResourceLink
Documentation/docs
DiscordJoin
GitHubMeshJS/mesh
Guides/guides

On this page