<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jeff Gatbonton</title>
    <description>The latest articles on DEV Community by Jeff Gatbonton (@jeffgat).</description>
    <link>https://dev.to/jeffgat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1071613%2Fad0fbe71-1a9e-479b-ae31-9ba5a4a05db7.jpeg</url>
      <title>DEV Community: Jeff Gatbonton</title>
      <link>https://dev.to/jeffgat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jeffgat"/>
    <language>en</language>
    <item>
      <title>Technical Frontend Deep Dives for Web3 Developers</title>
      <dc:creator>Jeff Gatbonton</dc:creator>
      <pubDate>Mon, 23 Jun 2025 00:07:48 +0000</pubDate>
      <link>https://dev.to/jeffgat/technical-frontend-deep-dives-for-web3-developers-3elh</link>
      <guid>https://dev.to/jeffgat/technical-frontend-deep-dives-for-web3-developers-3elh</guid>
      <description>&lt;p&gt;If you’re like me—a frontend dev who cut their teeth on design and found their freedom in crypto—then you know that building for Web3 is a constant tug-of-war between complexity and elegance.&lt;/p&gt;

&lt;p&gt;In this post, I’m diving into three of the most important frontend techniques that have helped me scale real-world dApps without losing sleep (or my users).&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Using Zustand/Jotai in Production Crypto dApps
&lt;/h2&gt;

&lt;p&gt;Global state in Web3 isn’t just UI fluff—it can represent real token balances, on-chain auth, wallet connections, and smart contract interactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Not Redux?
&lt;/h2&gt;

&lt;p&gt;Redux is a beast. It’s overkill for the lean, reactive needs of most Web3 dApps. Zustand and Jotai, on the other hand, give you atomic state management with way less boilerplate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zustand in Practice:
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;import { create } from 'zustand';&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const useWalletStore = create((set) =&amp;gt; ({
  address: null,
  setAddress: (addr) =&amp;gt; set({ address: addr }),
  chainId: null,
  setChainId: (id) =&amp;gt; set({ chainId: id }),
}));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No reducers. No context spaghetti. Just composable, lightweight state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Persistence and Middleware
&lt;/h2&gt;

&lt;p&gt;Zustand supports middleware for persisting to localStorage, syncing across tabs, or debugging without extra setup.&lt;/p&gt;

&lt;p&gt;Jotai is even more atomic—ideal for when you want to isolate individual pieces of state (like specific token values or component-scoped loading flags).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. SSR &amp;amp; Caching in Next.js for Blockchain-Based Frontends
&lt;/h2&gt;

&lt;p&gt;Let’s be real: most Web3 devs skip SSR. They slap up a bunch of useEffects and call it a day. But if you want SEO, faster Time to First Byte, or robust UX for unauthenticated users, server-side rendering matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Pitfalls:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Token balances fetched client-side only? Goodbye to instant feedback.&lt;/li&gt;
&lt;li&gt;Wallet-dependent UI flickering on page load? UX killer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solution: Hybrid Rendering + Caching
&lt;/h2&gt;

&lt;p&gt;Here’s what works for me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;getServerSideProps to fetch general data (e.g. token stats, protocol metrics)&lt;/li&gt;
&lt;li&gt;SWR on the client to hydrate and revalidate wallet-specific data&lt;/li&gt;
&lt;li&gt;Edge caching using Vercel or custom headers
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function getServerSideProps() {
  const prices = await fetchTokenPrices();
  return {
    props: { prices },
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember: blockchain data doesn’t change every second. Cache it wisely, rehydrate it fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Leveraging GraphQL in Web3 Apps with Live Token Data
&lt;/h2&gt;

&lt;p&gt;REST is a relic. GraphQL is how you tame on-chain chaos and offer your UI exactly what it needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why GraphQL?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fine-grained queries = less overfetching&lt;/li&gt;
&lt;li&gt;Combine multiple contracts/subgraphs into one UI layer&lt;/li&gt;
&lt;li&gt;Cleaner typings when using codegen (e.g. graphql-codegen)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tools I Use:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Graph Protocol (Subgraph APIs)&lt;/li&gt;
&lt;li&gt;Apollo Client for caching and reactive updates&lt;/li&gt;
&lt;li&gt;Satsuma/Subgrounds for querying across multiple chains&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query GetTokenHolders($id: String!) {
  token(id: $id) {
    id
    symbol
    holders(first: 10) {
      id
      balance
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pair this with useQuery in Apollo and you have real-time token data piped into a responsive, cache-aware UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts: Build Like It’s the New Internet
&lt;/h2&gt;

&lt;p&gt;Web3 isn’t a trend—it’s a rewrite of how value, identity, and code interact. But if the frontend sucks, no one cares what your protocol does.&lt;/p&gt;

&lt;p&gt;Zustand gives you composability. Next.js gives you speed. GraphQL gives you control. Combine these and you can build experiences that feel like magic—even when your users have no idea they just signed a transaction or bridged assets across chains.&lt;/p&gt;

&lt;p&gt;Design like an artist. Code like an engineer. Think like a rebel. That’s the frontend crypto stack.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>UI/UX in Web3</title>
      <dc:creator>Jeff Gatbonton</dc:creator>
      <pubDate>Thu, 29 May 2025 23:58:40 +0000</pubDate>
      <link>https://dev.to/jeffgat/uiux-in-web3-37p</link>
      <guid>https://dev.to/jeffgat/uiux-in-web3-37p</guid>
      <description>&lt;p&gt;I used to plate duck confit and brûlée creme in the underbelly of Toronto's kitchens, blasting punk and painting walls with tattoos. Today, I push pixels and code for decentralized applications. If you think the jump from culinary arts to code is wild, try going from Web2 to Web3 UX.&lt;/p&gt;

&lt;p&gt;As a self-taught designer-turned-frontend developer, I’ve lived through the chaotic beauty of the early web. But nothing prepared me for designing in Web3. It's not just harder—it's a fundamentally different beast. Here's what I've learned from the trenches of crypto UI/UX design.&lt;/p&gt;

&lt;p&gt;Why Designing for Wallet UX is 10x Harder than Web2&lt;/p&gt;

&lt;p&gt;In Web2, auth is simple. OAuth, cookies, sessions. You know the drill.&lt;/p&gt;

&lt;p&gt;In Web3? Your user is their wallet. That wallet could be MetaMask, Phantom, Rabby, or a cold storage Ledger buried in a hardware drawer. Each wallet behaves differently. There's no consistent design standard, no native onboarding flow, and zero margin for error.&lt;/p&gt;

&lt;p&gt;You can’t just say “Connect Wallet” and call it a day. You need to:&lt;/p&gt;

&lt;p&gt;Detect installed wallets (and gracefully handle when there are none)&lt;/p&gt;

&lt;p&gt;Guide users through complex, unfamiliar signing flows&lt;/p&gt;

&lt;p&gt;Communicate gas fees, network switching, and failed transactions without losing trust&lt;/p&gt;

&lt;p&gt;Handle multi-chain realities (good luck if you're bridging assets or supporting L2s)&lt;/p&gt;

&lt;p&gt;Every modal matters. Every interaction risks abandonment. This is design in an adversarial environment. UX is not a layer on top—it is the protocol.&lt;/p&gt;

&lt;p&gt;Breaking Down the UX Failures of Major dApps (and How to Fix Them)&lt;/p&gt;

&lt;p&gt;Let's not name names, but here are the repeat offenders I see in big-name dApps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wallet Connection Dead Ends&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nothing screams "bounce" like landing on a dApp that greets you with a broken Connect Wallet button. This happens more often than you'd believe. Fix: detect wallet presence, offer fallbacks, and never assume MetaMask is the default.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gas Fee Ambiguity&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;"Why did that cost $37?" is not a good post-onboarding sentiment. Many apps abstract fees to the point of confusion. Users need transparent previews, cost estimators, and fallback paths.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No State Management for On-Chain Events&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your user clicks "Stake." The transaction spins. Nothing happens. You lost them. Fix: use robust on-chain listeners, show pending states, and provide confirmations.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Unclear Transaction Purposes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Asking a user to sign an arbitrary message without explaining why? That's not trustless UX. That's lazy design.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mobile? What Mobile?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Too many dApps are built desktop-first. Yet in emerging markets, most users are mobile-only. Progressive enhancements and mobile-first design aren’t optional. They’re survival.&lt;/p&gt;

&lt;p&gt;How to Design a Seamless Onboarding Flow for Web3 Without Losing Users&lt;/p&gt;

&lt;p&gt;The traditional SaaS funnel? It's dead here. Your user doesn’t want to "sign up." They want to interact, swap, mint, or stake — now.&lt;/p&gt;

&lt;p&gt;Here’s how to onboard without losing your user:&lt;/p&gt;

&lt;p&gt;Progressive DisclosureDon’t show users 8 wallet options at once. Detect their environment and suggest the most likely wallet. Simplify decision trees.&lt;/p&gt;

&lt;p&gt;Pre-Onboarding EducationBrief walkthroughs, ghost tooltips, and inline help text can teach without preaching. Show users what "signing" does before they’re asked to do it.&lt;/p&gt;

&lt;p&gt;Friction Isn’t Always BadSometimes, a tiny delay (e.g. animation during wallet switching) is good. It reduces panic. Create UX that feels confident and guided.&lt;/p&gt;

&lt;p&gt;Track UX Drop-Off PointsAnalytics still matter. Where are users leaving? Where are they hesitating? Use this to iterate your flow like you would in Web2.&lt;/p&gt;

&lt;p&gt;Fail Loud, But FriendlyWhen things go wrong (and they will), don’t hide it. Surface helpful error messages. Encourage retries. Offer backup options.&lt;/p&gt;

&lt;p&gt;Final Thoughts: Design Like a Crypto Punk&lt;/p&gt;

&lt;p&gt;Web3 is chaotic, unregulated, full of scams, innovation, and promise. It's punk rock. It's permissionless. It forces you to build trust through UX, not marketing.&lt;/p&gt;

&lt;p&gt;To design in Web3 is to rebel against the status quo of Web2 design systems. It means embracing broken standards and still finding ways to guide, educate, and delight users. If you're a designer or frontend dev making the leap, prepare to unlearn everything.&lt;/p&gt;

&lt;p&gt;Remember: frictionless doesn’t mean trustless. And in Web3, the best UX earns the user’s trust at every interaction.&lt;/p&gt;

&lt;p&gt;We’re not just building products. We’re building new paradigms. And that’s a frontier worth designing for.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
