Mini Apps
Farcaster Mini Apps (previous Frames) provide an easy way for developers to build rich in-app experiences, and Orbiter makes it simple to host one! Follow our quickstart below or read more in depth the pieces that go into Mini Apps.
Quickstart
-
Create a free account and get an API key
-
Install the orbiter-cli and authorize it
Terminal window npm i -g orbiter-cliorbiter auth -
Launch a Mini App in one command
Terminal window orbiter miniapp -
Update the Mini App with
deploy
Terminal window orbiter deploy
Manual Setup
If you prefer to manually setup your Mini App we’ll walk you through the necessary components to make it work with Farcaster.
Project Setup
To be beging let’s start up a fresh project. We would reccomend using Vite with a framework like React.
npm create vite@latest mini-app
It will give you some choices, and for this tutorial we’ll choose React with Typescript. Once it’s finished setting up the project let’s move into it and install dependencies.
cd mini-appnpm install @farcaster/frame-sdk
Mini App SDK
Then with your text editor of choice open the src/App.tsx
and let’s paste in the following contents.
import { useState, useEffect, useCallback } from 'react'import './App.css'import sdk from '@farcaster/frame-sdk';import { Context } from '@farcaster/frame-sdk';
function App() { const [isSDKLoaded, setIsSDKLoaded] = useState(false); const [context, setContext] = useState<Context.FrameContext>(); const [isContextOpen, setIsContextOpen] = useState(false);
useEffect(() => { const load = async () => { setContext(await sdk.context); sdk.actions.ready(); }; if (sdk && !isSDKLoaded) { setIsSDKLoaded(true); load(); } }, [isSDKLoaded]);
const toggleContext = useCallback(() => { setIsContextOpen((prev) => !prev); }, []);
if (!isSDKLoaded) { return <div>Loading...</div>; }
return ( <div style={{ maxWidth: "400px", margin: "0 auto", padding: "0 16px" }}> <h1>Frames v2 Demo</h1>
<div> <h2>Context</h2> <button onClick={toggleContext} > <span> ➤ </span> Tap to expand </button>
{isContextOpen && ( <div style={{ overflow: 'auto', maxWidth: '100%' }}> <pre style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word', wordBreak: 'break-word', overflowWrap: 'break-word', maxWidth: '100%', fontSize: '14px' }}> {JSON.stringify(context, null, 2)} </pre> </div> )} </div> </div> )}
export default App
The most important part of this setup is the highlighted line:
sdk.actions.ready();
This sends a message to the Farcaster client that your Mini App is ready to communicate and help it load inside Farcaster. Of course there’s a whole lot more the SDK is capable of so we would highly recommend reading the documentation.
Embed Meta Tag
Next we’ll setup the embed meta tag. This provides Farcaster information similar to Opengraph data with images, description, etc. Inside the index.html
paste in the code below.
<!doctype html><html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vite + React + TS</title> <meta name="fc:frame" content='{"version":"next","imageUrl":"https://v2demo.orbiter.website/image.png","button":{"title":"Launch","action":{"type":"launch_frame","name":"Launch","url":"https://v2demo.orbiter.website","splashImageUrl":"https://v2demo.orbiter.website/splash.png","splashBackgroundColor":"#ffffff"}}}' /> </head> <body> <div id="root"></div> <script type="module" src="/src/main.tsx"></script> </body></html>
Here’s the same information but a bit easier to read.
<meta name="fc:frame" content=' { "version":"next", "imageUrl":"https://miniapp.orbiter.website/image.png", "button":{ "title":"Launch", "action": { "type":"launch_frame", "name":"Launch", "url":"https://miniapp.orbiter.website", "splashImageUrl":"https://miniapp.orbiter.website/splash.png", "splashBackgroundColor":"#ffffff" } } } ' />
The key is to update the domain from miniapp.orbiter.website
to whatever your Orbiter domain or custom domain is going to be. If you don’t have that yet that’s ok, just don’t forget to update it later!
Manifest
Once you save the index.html
file the last thing we need to add is the Manifest. This is a JSON file that lives inside public/.well-known/farcaster.json
. To make this run the following commands one at a time.
mkdir public/.well-knowntouch public/.well-known/farcaster.json
Inside farcaster.json
paste in the following JSON:
{ "accountAssociation": { "header": "", "payload": "", "signature": "" }, "frame": { "version": "1", "name": "Mini App", "iconUrl": "https://miniapp.orbiter.website/icon.png", "homeUrl": "https://miniapp.orbiter.website", "imageUrl": "https://miniapp.orbiter.website/image.png", "buttonTitle": "Launch", "splashImageUrl": "https://miniapp.orbiter.website/splash.png", "splashBackgroundColor": "#ffffff" }}
The Manifest is info used by Farcaster for when a user wants to “add” your mini app, similar to installing an app from the app store. It includes basic information like images, name of the app, button title, etc. It also can include the accountAssociation
which is used to verify that the app is owned by your Farcaster account. More information on that here.
You’ll notice that you might be missing some of the images listed here, so if you want install those run the following command:
curl https://docs.orbiter.host/mini-app-images.zip -o images.zip && unzip images.zip -d public
Deployment
With all of our pieces in place we can now deploy our Mini App! There are a few ways you can deploy to Orbiter.
CLI
Perhaps the easiest route is to use the Orbiter CLI, which has a handy command to create a new deployment or update a previous one called deploy
.
orbiter deploy
This will save an orbiter.json
configuration that will be used for future updates and deployments.
GitHub Action
Depending on the app you can create an automatic deployment using Orbiter’s GitHub action. More infor can be found below.
Orbiter App
If you prefer to use a GUI, the first thing you need to do is build your project.
npm run build
For more frameworks this will create a static build folder like dist
. Once you have this visit app.orbiter.host and click Upload Site
in the top right, select your folder, then choose a subdomain.
Developing and Testing
At the time of writing the best way to test and debug Mini Apps is inside the Warpcast Dev Portal using either the Embed or Manifest tool. With either of these you can pull up your app by URL / domain and verify the information and test the functionality.
If you want to test locally you will need a tunnel with a service like Ngrok or Tailscale. Both Justin and I (Steve) are pretty big fans of Tailscale for this application because it’s free and super easy to use. All you need to do in order to get started is:
- Create a free account
- Install Tailscale
- Run
tailscale up
- Then run
tailcale funnel <PORT_NUMBER>
For example, if you were using our Vite templates that by default run on http://localhost:5173
then you would run tailscale funnel 5173
and you should get a URL you can paste into the Mini app Embed or Manifest tool to open the app. The Farcaster team is working on better ways to test Mini Apps without the need of a tunnel so we will do our best to keep this section up to date!
Publishing
When your app is ready to publish there are a few things you will want to make sure you have completed first.
- Updated the images in your
public
folder - Update the Embed Meta Tag with your info
- Update the Manifest with your info
- Update the Account Association
The last step is truly the last one you will likely want to do, as it requires all of the domain info to be up to date. Generating the accountAssociation
signatures can only be done through the Warpcast mobile app or through the Warpcast Developer Portal which will prompt you to sign it in your mobile app as well. Once you have the signature you will want to copy and past that object into the manifest.
{ "accountAssociation": { "header": "eyJmaWQiOjM2MjEsInR5cGUiOiJjdXN0b2R5Iiwia2V5IjoiMHgyY2Q4NWEwOTMyNjFmNTkyNzA4MDRBNkVBNjk3Q2VBNENlQkVjYWZFIn0", "payload": "eyJkb21haW4iOiJ5b2luay5wYXJ0eSJ9", "signature": "MHgwZmJiYWIwODg3YTU2MDFiNDU3MzVkOTQ5MDRjM2Y1NGUxMzVhZTQxOGEzMWQ5ODNhODAzZmZlYWNlZWMyZDYzNWY4ZTFjYWU4M2NhNTAwOTMzM2FmMTc1NDlmMDY2YTVlOWUwNTljNmZiNDUxMzg0Njk1NzBhODNiNjcyZWJjZTFi" }, "frame": { "version": "1", "name": "Yoink!", "iconUrl": "https://yoink.party/logo.png", "homeUrl": "https://yoink.party/framesV2/", "imageUrl": "https://yoink.party/framesV2/opengraph-image", "buttonTitle": "🚩 Start", "splashImageUrl": "https://yoink.party/logo.png", "splashBackgroundColor": "#f5f0ec", "webhookUrl": "https://yoink.party/api/webhook" }}
Client vs Backend
Orbiter currently only supports static apps, which means they must be rendered client side. If you need a backend for your Mini App on Orbiter we would highly recommend using Hono on a Cloudflare Worker. It’s can be initialized and deployed in just a few commands!
npm create hono@latest my-app # Select Cloudflare Workers
cd my-app
npm install
npx wrangler login
npm run deploy
Questions
Stuck and need some help? Post your question in the Orbiter Channel!