How to Think About Frames

Christian Montoya
5 min readJan 28, 2024

2 days ago, the team behind Farcaster (the protocol) and Warpcast (the reference client for the Farcaster protocol) launched Frames. This exciting new feature kicked off a flurry of developer activity, with many useful, funny, and sometimes very weird Frames being shared in the feed, and also contributed to the highest ever daily active users on Warpcast — over 10k users in one day.

Photo from Mondrian — Color in Motion strategy game

I’ve seen a few people trying to get up to speed on what Frames are and what can be done with them, so I’m going to try to explain that here and share some mental frameworks that may inspire future Frames projects. But first, if you want to see some example Frames, here’s a few:

  • Polls Frame lets you vote on a poll with up to 4 options, and shows you the results of the poll inside the Frame — if you go to the site, you can make your own poll and share it on your feed
  • Paragraph (blog & newsletter platform) Frame lets you subscribe to a Paragraph newsletter with one click, without leaving the feed
  • Random Chublins Frame lets you click to load a random Chublin from the Chublins NFT collection
  • Nethria Frame embeds the Nethria text adventure game into a Frame

OK, now that you’ve seen some examples, let’s talk about what’s going on here. You might be tempted to think that Frames are like HTML IFRAMES, but that’s only because the name is a bit of a misnomer. A Frame is not an embedded webpage. The content of the Frame is not interactive. A better way to think of a Frame is a typical social media embed — if you’ve seen open graph tags, it’s like that — but with buttons underneath. The content of the Frame is just an image. It can be animated (hello again, GIFs!) and savvy devs can generate images dynamically to include any kind of content, but these images are not interactive. The real magic is in the buttons. When a user clicks one of those buttons, a POST request is sent with a signed payload to the URL provided in the Frame, and that URL can respond with another Frame. The signed payload includes which button was pressed and a cryptographic hash that can be used to reliably identify the user that submitted it. That last part is important, because it means you can filter out bots from interacting with your Frame (or hitting the endpoint directly). If you’ve ever encountered a CAPTCHA when attempting to use an online service, that’s an old fashioned way of identifying humans and filtering out bots. Even ChatGPT has to employ CAPTCHAs (and users do not like them). With Frames, however, you can decode the signed payload and find the ID of the user that submitted the request, for any action that you want to limit to real users.

Take note, dear reader, that so far I have not mentioned anything about a blockchain, smart contracts, or wallets. Frames, and the server side component that powers them, do not rely on any of these things. A Frame can be more like a dapp, or even just a traditional web app. As of today, Frames do not use wallets like MetaMask or connector services like WalletConnect. However, you can build web3-enabled functionality into a Frame. I’ll explain how later.

So now that I have explained what Frames are and what they are not, you might want to read the Frames spec which explains how they work in more details and how to build on them. Go ahead, I’ll wait.

OK, let’s talk about what you can do with Frames.

Better Embeds

At the very least, a Frame is an interactive embed. Imagine if Google made a Frame for Google Slides. Any time you link to a Google Slides presentation in your feed, instead of just showing an image preview of the first slide, it shows the image preview + buttons underneath. You can click these buttons to navigate forward and backwards through the slides — essentially, you can view the whole slideshow right in the Frame. That would actually be a pretty simple Frame implementation.

Connected Embeds

Let’s take things a step further. Take OpenSea for example. You can “fave” any NFT on OpenSea to add it to your favorites. If OpenSea used Frames, then when any user shares an NFT page from OpenSea on the feed, underneath the image there could be a button to add it as a favorite. The way this would work is when the OpenSea backend receives the signed message, it decodes it to find the ID of the user that clicked the button, then looks up the address associated with that user. Keep in mind that not all Farcaster users have a wallet address associated with their Farcaster account, so the OpenSea backend could decide what to do if it doesn’t find a wallet address, or just show a message in the Frame saying there’s no wallet for that user, but in the event that a user does have a wallet address, then OpenSea could add that NFT to that user’s favorites. Thus, users would be able to “fave” NFTs without ever leaving the feed.

Sponsored Actions

Now you may be wondering, how can Frames power blockchain activity? There has to be some transaction for that to happen, right? Well, yes, but that transaction can be sponsored and facilitated by the server. You may have seen the first NFT mint in a Frame, which lets users mint the NFT on Base with just one click. The way it works is like this: the dev created an NFT contract and put up funds ahead of time to cover the cost of each mint. When a user clicks the mint button in the Frame, the server finds the connected address for that user, and then mints the NFT with the developer’s wallet to the user’s address. There is a transaction, but the user isn’t doing the transaction, and the user doesn’t pay for it.

At this point you might want to ask, what if the user could pay for it? Here’s how that might work: let’s say you have a service where users can go and delegate for a smart contract or a server to handle some funds on their behalf (think of PayPal, where you can top up a balance and then authorize it to pay for things on your behalf, but cooler than that). Users would create accounts on this service and top up those accounts with some funds. Then, when users interact with a Frame from that service, the service gets the signed request, finds the account for that user, and performs the onchain action (mint, send, etc) using the prepaid balance for that user. This is entirely possible today, and I suspect we will see Frames like this soon.

Hopefully this gives you some ideas for Frames projects. I plan to build some more myself, and will share some more about it when I can. If this was helpful, or you want to talk more about Frames, let’s connect on Warpcast. Thanks for reading!



Christian Montoya

Views expressed here do not represent those of my employer.