Skip to content

Publishing your app

Publishing Mini Apps involves providing information like who developed the app, how it should be displayed, and what its capabilities are.

Since Farcaster is a decentralized network with multiple clients, publishing is done by hosting a manifest file at /.well-known/farcaster.json on the domain your app is hosted on rather than submitting information directly to a single entity.

discover mini apps

Published Mini Apps can be discovered in App Stores.

Steps

Choose a domain

A Mini App is associated with a single domain (i.e. rewards.warpcast.com). This domain serves as the identifier for your app and can't be changed later so you should choose a stable domain.

There's no limit on the number of apps you can create. You can create a separate domain specifically for development purposes if needed.

Host a manifest file

Host a manifest file on your chosen domain at /.well-known/farcaster.json.

For now we'll create an empty file:

touch public/.well-known/farcaster.json

Farcaster Hosted Manifests (closed beta)

Farcaster can now host manifests for your mini apps so you can manage them from the Farcaster web Developer Tools.

Learn more

Instead of serving a /.well-known/farcaster.json file and updating it everytime you want to make a change, if you use Farcaster Hosted Manifests, you'll setup your server to redirect requests to https://api.farcaster.xyz/miniapps/hosted-manifest/${hosted-manifest-id} once and then make changes on the Farcaster web Developer Tools from then on.


Setting up redirects

All web servers support redirects. The following are examples of how to setup redirects in popular frameworks.

Redirects in Next.js
// next.config.js
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  async redirects() {
    return [
      {
        source: '/.well-known/farcaster.json',
        destination: 'https://api.farcaster.xyz/miniapps/hosted-manifest/1234567890',
        permanent: false,
      },
    ]
  },
}
 
export default nextConfig
Redirects in Express
const express = require('express')
const app = express()
 
app.get('/.well-known/farcaster.json', (req, res) => {
  res.redirect(307, 'https://api.farcaster.xyz/miniapps/hosted-manifest/1234567890')
})
Redirects in Hono
import { Hono } from 'hono'
const app = new Hono()
 
app.get('/.well-known/farcaster.json', (c) => {
  return c.redirect('https://api.farcaster.xyz/miniapps/hosted-manifest/1234567890', 307)
})
Redirects in Remix
// app/routes/.well-known/farcaster.json.tsx
import { redirect } from '@remix-run/node'
 
export const loader = () => {
  return redirect('https://api.farcaster.xyz/miniapps/hosted-manifest/1234567890', 307)
}
 
export default () => null

Define your application configuration

A Mini App has metadata that is used by Farcaster clients to host your app. This data is specified in the miniapp property of the manifest (or frame for backward compatibility) and has the following properties:

PropertyTypeRequiredDescriptionConstraints
versionstringYesManifest version.Must be '1'.
namestringYesMini App name.Max length 32 characters
homeUrlstringYesDefault launch URLMax length 1024 characters.
iconUrlstringYesIcon image URLMax length 1024 characters.
Image must be 1024x1024px PNG, no alpha.
splashImageUrlstringNoURL of image to show on loading screen.Max length 32 characters. Must be 200x200px.
splashBackgroundColorstringNoHex color code to use on loading screen.Hex color code.
webhookUrlstringNoURL to which clients will POST events.Max length 1024 characters.
Must be set if the Mini App application uses notifications.
subtitlestringNoShort description under app nameMax 30 characters, no emojis or special characters
descriptionstringNoPromotional message for Mini App PageMax 170 characters, no emojis or special characters
screenshotUrlsarrayNoVisual previews of the appPortrait, 1284 x 2778, max 3 screenshots
primaryCategorystringNoPrimary category of appOne of: games, social, finance, utility, productivity, health-fitness, news-media, music, shopping, education, developer-tools, entertainment, art-creativity
tagsarrayNoDescriptive tags for filtering/searchUp to 5 tags, max 20 characters each. Lowercase, no spaces, no special characters, no emojis.
heroImageUrlstringNoPromotional display image1200 x 630px (1.91:1)
taglinestringNoMarketing taglineMax 30 characters
ogTitlestringNoOpen Graph titleMax 30 characters
ogDescriptionstringNoOpen Graph descriptionMax 100 characters
ogImageUrlstringNoOpen Graph promotional image1200 x 630px (1.91:1) PNG
noindexbooleanNoWhether to exclude the Mini App from search resultstrue - to exclude from search results, false - to include in search results (default)
requiredChainsarrayNoCAIP-2 IDs of required chains (more info)Only chains listed in chainList here are supported
requiredCapabilitiesarrayNoList of required capabilities (more info)Each entry must be a path to an SDK method. Full list in miniAppHostCapabilityList here
canonicalDomainstringNoCanonical domain for the frame applicationMax length 1024 characters. Must be a valid domain name without protocol, port, or path (e.g., app.example.com).
imageUrlstringNo[DEPRECATED] Default image to show if shared in a feed.Max length 1024 characters.
Image must be 3:2 aspect ratio.
buttonTitlestringNo[DEPRECATED] Default button title to show if shared in a feed.Max length 32 characters.

Here's an example farcaster.json file:

{
  "miniapp": {
    "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",
    "requiredChains": [
      "eip155:8453"
    ],
    "requiredCapabilities": [
      "actions.signIn",
      "wallet.getEthereumProvider",
      "actions.swapToken"
    ]
  }
}

Hybrid & SSR-friendly detection

Some apps serve both as a Farcaster Mini App and a website from the same domain. When you want to fetch specific resources during server-side rendering (SSR) or conditionally lazy-load the SDK on the client, add a lightweight flag that only Mini-App launch URLs include

Two suggested patterns
PatternHow it looksWhy use it
Dedicated path/your/path/.../miniappEasiest to match on the server
Well-known query paramhttps://example.com/page?miniApp=trueWorks when a single page serves both modes

Example

// app/layout.tsx
'use client'
import { useEffect } from 'react'
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    const url = new URL(window.location.href)
    const isMini =
      url.pathname.startsWith('/mini') ||
      url.searchParams.get('miniApp') === 'true'
 
    if (isMini) {
      import('@farcaster/miniapp-sdk').then(({ sdk }) => {
        // Mini-App–specific bootstrap here
        // e.g. sdk.actions.ready()
      })
    }
  }, [])
 
  return children
}

On the server you can do the same check to skip expensive Mini App work during SSR.

Verifying ownership

A Mini App is owned by a single Farcaster account. This lets users know who they are interacting with and developers get credit for their work.

verified author

Verification is done by placing a cryptographically signed message in the accountAssociation property of your farcaster.json.

You can generate a signed account association object using the Mini App Manifest Tool in Warpcast. Take the output from that tool and update your farcaster.json file.

Here's an example farcaster.json file for the domain yoink.party with the account association:

{
  "accountAssociation": {
    "header": "eyJmaWQiOjkxNTIsInR5cGUiOiJjdXN0b2R5Iiwia2V5IjoiMHgwMmVmNzkwRGQ3OTkzQTM1ZkQ4NDdDMDUzRURkQUU5NDBEMDU1NTk2In0",
    "payload": "eyJkb21haW4iOiJyZXdhcmRzLndhcnBjYXN0LmNvbSJ9",
    "signature": "MHgxMGQwZGU4ZGYwZDUwZTdmMGIxN2YxMTU2NDI1MjRmZTY0MTUyZGU4ZGU1MWU0MThiYjU4ZjVmZmQxYjRjNDBiNGVlZTRhNDcwNmVmNjhlMzQ0ZGQ5MDBkYmQyMmNlMmVlZGY5ZGQ0N2JlNWRmNzMwYzUxNjE4OWVjZDJjY2Y0MDFj"
  },
  "miniapp": {
    "version": "1",
    "name": "Rewards",
    "iconUrl": "https://rewards.warpcast.com/app.png",
    "splashImageUrl": "https://rewards.warpcast.com/logo.png",
    "splashBackgroundColor": "#000000",
    "homeUrl": "https://rewards.warpcast.com",
    "webhookUrl": "https://client.farcaster.xyz/v1/creator-rewards-notifs-webhook",
    "subtitle": "Top Warpcast creators",
    "description": "Climb the leaderboard and earn rewards by being active on Warpcast.",
    "screenshotUrls": [
      "https://rewards.warpcast.com/screenshot1.png",
      "https://rewards.warpcast.com/screenshot2.png",
      "https://rewards.warpcast.com/screenshot3.png"
    ],
    "primaryCategory": "social",
    "tags": [
      "rewards",
      "leaderboard",
      "warpcast",
      "earn"
    ],
    "heroImageUrl": "https://rewards.warpcast.com/og.png",
    "tagline": "Top Warpcast creators",
    "ogTitle": "Rewards",
    "ogDescription": "Climb the leaderboard and earn rewards by being active on Warpcast.",
    "ogImageUrl": "https://rewards.warpcast.com/og.png"
  }
}