Journal

Farcaster Frame Native iOS Renderer: The Build Guide

Two rendering paths, one per Frame version. Here is exactly what native means for v1 Frames and for v2 Mini Apps on iOS.

Farcaster Frame Native iOS Renderer: The Build Guide: a glass iPhone app-grid icon on a mint and teal gradient

TL;DR

A native iOS renderer for Farcaster Frames splits by version. A v1 Frame is a static image plus up to four buttons in meta tags, so you render it fully native and POST a signed action per tap. A v2 Frame, rebranded as a Mini App, is a full web app, so native means hosting it in a WKWebView with the postMessage SDK bridge and wrapping it in native chrome: splash, vertical modal, close. Frames drove a 50x jump in Farcaster activity and helped the protocol raise $150 million, so the renderer is worth building to spec. Detect the version first, then choose the path.

A native iOS renderer for Farcaster Frames means two different things depending on the version, and mixing them up is why most attempts stall. A v1 Frame is a static image with up to four buttons, declared in meta tags, so you can render it fully native: parse the tags, draw the image at a 3:2 ratio, lay out the buttons, and POST each tap to the frame server. A v2 Frame, rebranded as a Mini App in early 2025, is a full interactive web app, so native means hosting it in a WKWebView with the postMessage bridge and wrapping it in native chrome, the splash, the vertical modal, and the close control. Frames are why this matters: after the feature shipped, Farcaster saw a 50x increase in network activity and the protocol raised $150 million at a $1 billion valuation. Build the renderer to match the spec, not a guess.

What is a Farcaster Frame, and what changed in v2?

A Frame turns a social post into something interactive. In v1, the Farcaster spec defined a Frame as OpenGraph-style meta tags: an image, up to four buttons, and a post URL the client calls when a button is tapped. The client does the rendering, the frame server does the logic, and the exchange is a signed message so the server knows which user acted.

Version 2 changed the model entirely. Frames v2 were rebranded to Mini Apps and are now full-screen web applications loaded in an iframe, talking to the host through window.postMessage and a JavaScript SDK that exposes user context, wallet actions, and notifications. The preview in the feed is still an image with a button, shown at 3:2, but tapping it opens a Mini App in a vertical modal rather than posting back a new image. Knowing which version a cast uses decides your entire rendering path.

How do you render a v1 Frame natively on iOS?

You parse, draw, and POST. Fetch the cast’s embedded URL, read the fc:frame meta tags for the image, the button titles, and the post URL, then render a native card: the image constrained to 3:2, and a row of up to four buttons beneath it. This is ordinary SwiftUI or UIKit layout, no webview involved, which is what makes v1 fast and clean to render.

The interaction is where correctness lives. When a user taps a button, you build a frame action, sign it with the user’s app key in the JSON Farcaster Signature format, and POST it to the frame server. The response tells you what to do next: render a new frame, follow a redirect, open an external link, or start a transaction. Handle each button action type deliberately, and treat a redirect as untrusted by opening it in a Safari view controller rather than your app’s own web context. The broader discipline of building trustworthy on-chain screens carries over from designing web3 interfaces with AI.

How do you host a v2 Mini App natively?

You give a WKWebView a proper native shell and a message bridge. Load the Mini App URL in a WKWebView, register a WKScriptMessageHandler so the app’s postMessage calls reach native code, and answer the SDK’s requests for user context, wallet signing, and notification permission. The web app renders its own body; your job is everything around it.

The native chrome is what the spec expects and what makes it feel like part of the client. Show the splash screen during the transition, present the Mini App in a vertical modal sized to the device, and provide a clear close control. When the app requests a wallet action, route it to the user’s connected wallet with a native confirmation rather than letting the webview handle keys. For notifications, store the token and URL the host issues so the Mini App server can push later, the same account-and-token pattern behind a crypto wallet’s connect and sign flows.

Common mistakes building a Frame renderer

The security ones are the costly mistakes. Rendering a v1 button POST without signing it with the user’s key, or trusting the frame server’s redirect blindly, both open real abuse paths, so verify the signature format and sandbox every outbound link. For v2, giving the webview unfiltered access to wallet or native APIs defeats the point of a native host; the bridge should expose only the SDK surface the spec defines.

The UI mistakes are subtler. Letting the image break its 3:2 ratio, or blocking the feed while a Frame image loads, makes the whole timeline feel broken, so render a placeholder and swap the image in asynchronously. And forgetting that a cast may contain a plain link rather than a Frame means you show an empty card; detect the meta tags first and fall back to a normal link preview when they are absent, the same graceful degradation used in an on-chain swap interface.

Key takeaways: a native Farcaster Frame renderer

  • Detect the version first: v1 Frames render fully native, v2 Mini Apps run in a WKWebView with native chrome.
  • For v1, parse the fc:frame meta tags, draw the 3:2 image and up to four buttons, and POST a signed frame action for each tap.
  • For v2, host the Mini App in a webview, bridge window.postMessage to native, and supply user context, wallet, and notifications through the SDK.
  • Treat every redirect and wallet request as untrusted: sign actions, sandbox links, and confirm signing natively.
  • Preserve the 3:2 preview ratio and fall back to a normal link card when a cast has no Frame tags.

Frequently asked questions

How do I render Farcaster Frames natively on iOS? For v1 Frames, parse the fc:frame meta tags from the embedded URL, render the image at 3:2 with up to four native buttons, and POST a signed frame action to the post URL on each tap. For v2 Mini Apps, load the app in a WKWebView, bridge window.postMessage to native through a script message handler, and wrap it in a native splash and vertical modal. Detect which version the cast uses before choosing a path.

What is the difference between Frames v1 and v2? V1 Frames are static: an image plus up to four buttons declared in meta tags, with the client rendering and a frame server responding to POSTs. V2 Frames, now called Mini Apps, are full interactive web apps loaded in an iframe that talk to the host over a postMessage SDK with wallet and notification access. V1 renders natively; v2 runs in a webview.

Do I need a webview to render a Farcaster Frame? Not for v1. A v1 Frame is just an image and buttons, so you draw it with native views and never load a webview, which keeps the feed fast. You only need a WKWebView for v2 Mini Apps, because those are actual web applications, and even then the splash, modal, and wallet confirmation stay native.

How does the frame server know which user tapped a button? Each button POST carries a frame action signed with the user’s app key in the JSON Farcaster Signature format, so the server can verify identity without a password. Your renderer builds and signs that message; never send an unsigned action, because the server should reject it and any app that accepts unsigned actions is unsafe.

What image size should a Farcaster Frame use? The feed preview image renders at a 3:2 aspect ratio with the button row beneath it, and a v2 Mini App opens in a vertical modal sized to the device, roughly 424 by 695 pixels on web. Constrain the image to 3:2 in your layout and show a placeholder while it loads so the timeline never jumps.

Questions from the VP0 Vibe Coding community

How do I render Farcaster Frames natively on iOS?

For v1 Frames, parse the fc:frame meta tags from the embedded URL, render the image at 3:2 with up to four native buttons, and POST a signed frame action to the post URL on each tap. For v2 Mini Apps, load the app in a WKWebView, bridge window.postMessage to native through a script message handler, and wrap it in a native splash and vertical modal. Detect which version the cast uses before choosing a path.

What is the difference between Frames v1 and v2?

V1 Frames are static: an image plus up to four buttons declared in meta tags, with the client rendering and a frame server responding to POSTs. V2 Frames, now called Mini Apps, are full interactive web apps loaded in an iframe that talk to the host over a postMessage SDK with wallet and notification access. V1 renders natively; v2 runs in a webview.

Do I need a webview to render a Farcaster Frame?

Not for v1. A v1 Frame is just an image and buttons, so you draw it with native views and never load a webview, which keeps the feed fast. You only need a WKWebView for v2 Mini Apps, because those are actual web applications, and even then the splash, modal, and wallet confirmation stay native.

How does the frame server know which user tapped a button?

Each button POST carries a frame action signed with the user's app key in the JSON Farcaster Signature format, so the server can verify identity without a password. Your renderer builds and signs that message; never send an unsigned action, because the server should reject it and any app that accepts unsigned actions is unsafe.

What image size should a Farcaster Frame use?

The feed preview image renders at a 3:2 aspect ratio with the button row beneath it, and a v2 Mini App opens in a vertical modal sized to the device, roughly 424 by 695 pixels on web. Constrain the image to 3:2 in your layout and show a placeholder while it loads so the timeline never jumps.

Part of the Native Apple & SwiftUI: The iOS Ecosystem hub. Browse all VP0 topics →

Keep reading

Decentralized VPN Node Selector UI in SwiftUI, Free: the App Store logo on a glass tile over a blue gradient with bubbles
Guides 5 min read

Decentralized VPN Node Selector UI in SwiftUI, Free

Build a decentralized VPN node selector UI in SwiftUI from a free template. Browse nodes, see status, and connect, with the tunnel caveat handled honestly.

Lawrence Arya · June 1, 2026
Face ID Biometric Login Setup with Local App State (SwiftUI): a glowing iPhone home-screen icon on a purple and blue gradient
Guides 6 min read

Face ID Biometric Login Setup with Local App State (SwiftUI)

Wire Face ID login in SwiftUI: LocalAuthentication for the biometric check, one in-memory isUnlocked flag for state, and the session token in the Keychain.

Lawrence Arya · July 1, 2026
Best Fonts for Mobile Apps in 2026 (SwiftUI Guide): a reflective 3D App Store icon on a blue and purple gradient
Guides 10 min read

Best Fonts for Mobile Apps in 2026 (SwiftUI Guide)

SF Pro is still the best default for iOS in 2026: free, Dynamic Type ready, and tuned for screens. Here is when a custom font is worth it, and how to set it up.

Lawrence Arya · June 11, 2026
Spline 3D Model Background in SwiftUI: A Practical Guide: a reflective 3D App Store icon on a blue and purple gradient
Guides 9 min read

Spline 3D Model Background in SwiftUI: A Practical Guide

A Spline scene behind a SwiftUI interface looks alive because the GPU draws it live. Here is the embed, the performance caps, and when to choose SceneKit.

Lawrence Arya · June 10, 2026
SwiftUI App Intents Template for Apple Intelligence Apps: a glossy App Store icon on a blue, pink and orange gradient with bubbles
Guides 9 min read

SwiftUI App Intents Template for Apple Intelligence Apps

App Intents are how Apple Intelligence, Siri, Shortcuts, and Spotlight reach an app. Here is the template structure that gives an agent the right pattern.

Lawrence Arya · June 10, 2026
SwiftUI Code Audit Service: What to Buy and What It Costs: the App Store logo as a glossy glass icon on a purple and blue gradient with floating bubbles
Guides 9 min read

SwiftUI Code Audit Service: What to Buy and What It Costs

A SwiftUI code audit is judgment as a deliverable: a ranked map of what is fragile in your AI-built app. Here is what to buy, prepare, and expect to pay for.

Lawrence Arya · June 10, 2026