# Farcaster Mini Apps
## Context
When your app is opened it can access information about the session from
`sdk.context`. This object provides basic information about the user, the
client, and where your app was opened from:
```ts
export type FrameContext = {
user: {
fid: number;
username?: string;
displayName?: string;
pfpUrl?: string;
};
location?: FrameLocationContext;
client: {
clientFid: number;
added: boolean;
safeAreaInsets?: SafeAreaInsets;
notificationDetails?: FrameNotificationDetails;
};
};
```
### Properties
#### `location`
Contains information about the context from which the Mini App was launched.
```ts
export type CastEmbedLocationContext = {
type: 'cast_embed';
embed: string;
cast: {
fid: number;
hash: string;
};
};
export type NotificationLocationContext = {
type: 'notification';
notification: {
notificationId: string;
title: string;
body: string;
};
};
export type LauncherLocationContext = {
type: 'launcher';
};
export type ChannelLocationContext = {
type: 'channel';
channel: {
/**
* Channel key identifier
*/
key: string;
/**
* Channel name
*/
name: string;
/**
* Channel profile image URL
*/
imageUrl?: string;
};
};
export type LocationContext =
| CastEmbedLocationContext
| NotificationLocationContext
| LauncherLocationContext
| ChannelLocationContext;
```
##### Cast Embed
Indicates that the Mini App was launched from a cast (where it is an embed).
```ts
> sdk.context.location
{
type: "cast_embed",
cast: {
fid: 3621,
hash: "0xa2fbef8c8e4d00d8f84ff45f9763b8bae2c5c544",
}
}
```
##### Notification
Indicates that the Mini App was launched from a notification triggered by the frame.
```ts
> sdk.context.location
{
type: "notification",
notification: {
notificationId: "f7e9ebaf-92f0-43b9-a410-ad8c24f3333b"
title: "Yoinked!",
body: "horsefacts captured the flag from you.",
}
}
```
##### Launcher
Indicates that the Mini App was launched directly by the client app outside of a context, e.g. via some type of catalog or a notification triggered by the client.
```ts
> sdk.context.location
{
type: "launcher"
}
```
#### `user`
Details about the calling user which can be used to customize the interface. This should be considered untrusted since it is passed in by the application, and there is no guarantee that it was authorized by the user.
```ts
export type AccountLocation = {
placeId: string;
/**
* Human-readable string describing the location
*/
description: string;
};
export type UserContext = {
fid: number;
username?: string;
displayName?: string;
/**
* Profile image URL
*/
pfpUrl?: string;
location?: AccountLocation;
};
```
```ts
> sdk.context.user
{
"fid": 6841,
"username": "deodad",
"displayName": "Tony D'Addeo",
"pfp": "https://i.imgur.com/dMoIan7.jpg",
"bio": "Building @warpcast and @farcaster, new dad, like making food",
"location": {
"placeId": "ChIJLwPMoJm1RIYRetVp1EtGm10",
"description": "Austin, TX, USA"
}
}
```
```ts
type User = {
fid: number;
username?: string;
displayName?: string;
pfp?: string;
bio?: string;
location?: {
placeId: string;
description: string;
};
};
```
#### client
Details about the Farcaster client running the Mini App. This should be considered untrusted
* `clientFid`: the self-reported FID of the client (e.g. 9152 for Warpcast)
* `added`: whether the user has added the Mini App to the client
* `safeAreaInsets`: insets to avoid areas covered by navigation elements that obscure the view
* `notificationDetails`: in case the user has enabled notifications, includes the `url` and `token` for sending notifications
```ts
export type SafeAreaInsets = {
top: number;
bottom: number;
left: number;
right: number;
};
export type ClientContext = {
clientFid: number;
added: boolean;
notificationDetails?: FrameNotificationDetails;
safeAreaInsets?: SafeAreaInsets;
};
```
```ts
> sdk.context.client
{
clientFid: 9152,
added: true,
safeAreaInsets: {
top: 0,
bottom: 20,
left: 0,
right: 0,
};
notificationDetails: {
url: "https://api.warpcast.com/v1/frame-notifications",
token: "a05059ef2415c67b08ecceb539201cbc6"
}
}
```
```ts
type FrameNotificationDetails = {
url: string;
token: string;
};
type SafeAreaInsets = {
top: number;
bottom: number;
left: number;
right: number;
};
type ClientContext = {
clientFid: number;
added: boolean;
safeAreaInsets?: SafeAreaInsets;
notificationDetails?: FrameNotificationDetails;
};
```
##### Using safeAreaInsets
Mobile devices render navigation elements that obscure the view of an app. Use
the `safeAreaInsets` to render content in the safe area that won't be obstructed.
A basic usage would to wrap your view in a container that adds margin:
```
...your app view
```
However, you may want to set these insets on specific elements: for example if
you have tab bar at the bottom of your app with a different background, you'd
want to set the bottom inset as padding there so it looks attached to the
bottom of the view.
## Client Events
When a user interacts with your app events will be sent from the Farcaster
client to your application client.
Farcaster clients emit events to directly to your app client while it is open that can
be used to update your UI in response to user actions.
To listen to events, you have to use `sdk.on` to register callbacks ([see full
example](https://github.com/farcasterxyz/frames-v2-demo/blob/20d454f5f6b1e4f30a6a49295cbd29ca7f30d44a/src/components/Demo.tsx#L92-L124)).
Listeners can be cleaned up with `sdk.removeListener()` or sdk.removeAllListeners()\`.
### Events
#### frameAdded
The user added the Mini App.
#### frameRemoved
The user removed the Mini App.
#### notificationsEnabled
The user enabled notifications after previously having them disabled.
#### notificationsDisabled
The user disabled notifications.
## Getting Started
import { Caption } from '../../components/Caption';
### Overview
Mini apps are web apps built with HTML, CSS, and Javascript that can be discovered
and used within Farcaster clients. You can use an SDK to access native
Farcaster features, like authentication, sending notifications, and interacting
with the user's wallet.
### Quick Start
For new projects, you can set up an app using the
[@farcaster/create-mini-app](https://github.com/farcasterxyz/frames/tree/main/packages/create-mini-app)
CLI. This will prompt you to set up a project for your app.
:::code-group
```bash [npm]
npm create @farcaster/mini-app
```
```bash [pnpm]
pnpm create @farcaster/mini-app
```
```bash [yarn]
yarn create @farcaster/mini-app
```
:::
Remember, you can use whatever your favorite web framework is to build Mini
Apps so if these options aren't appealing you can setup the SDK in your own
project by following the instructions below.
### Manual Setup
For existing projects, install the Frames SDK:
#### Package Manager
:::code-group
```bash [npm]
npm install @farcaster/frame-sdk
```
```bash [pnpm]
pnpm add @farcaster/frame-sdk
```
```bash [yarn]
yarn add @farcaster/frame-sdk
```
:::
#### CDN
If you're not using a package manager, you can also use the Frame SDK via an
ESM-compatible CDN such as esm.sh. Simply add a `
```
### Building with AI
These docs are LLM friendly so that you use the latest models to build your
applications.
1. Use the Ask in ChatGPT buttons available on each page to interact with the
documentation.
2. Use the llms-full.txt to keep your LLM up to date with these docs:
Adding the Mini App docs to Cursor
#### How does this work?
This entire site is converted into a single markdown doc that can fit inside
the context window of most LLMs. See [The /llms.txt file](https://llmstxt.org/)
standards proposal for more information.
### Next Steps
You'll need to do a few more things before distributing your app to users:
1. publish the app by providing information about who created it and how it should displayed
2. make it sharable in feeds
## Specification
A frame is full-screen application that renders inside a Farcaster app.
It can be embedded in feeds in a compact form which includes an image and a button which opens the frame. When the button is clicked the frame URL is rendered in an in-app browser. Developers can build anything that renders in a browser and can use a JavaScript SDK to trigger actions like saving the frame or requesting an onchain transaction.
Frames will have access to:
1. Context: information about the user's Farcaster account and where the frame was called from
2. Actions: APIs to request the parent app to do certain things on the frame's behalf
3. Wallet: an Ethereum provider to request transactions and signatures from the connected wallet
Here's an example of a frame using a wallet to complete a transaction:

### Frame URL Specifications
A URL is considered a valid frame if it includes an embed tag in its HTML ``. An optional manifest file at a well known location at the root of the domain can be provided for additional provenance and appearance information for Farcaster clients.
#### Versioning
Frames will follow [semantic versioning](https://semver.org/) and frames must declare the version that they support. Apps will choose to render frames based on the versions they can support.
#### Frame Embed Metatags
A frame URL must have a FrameEmbed in a serialized form in the `fc:frame` meta tag in the HTML ``. When this URL is rendered in a cast, the image is displayed in a 3:2 ratio with a button underneath. Clicking the button will open an app frame to the provided action url and use the splash page to animate the transition.
```html
```
```ts
type FrameEmbed = {
// Frame spec version. Required.
// Example: "next"
version: 'next';
// Frame image.
// Max 512 characters.
// Image must be 3:2 aspect ratio and less than 10 MB.
// Example: "https://yoink.party/img/start.png"
imageUrl: string;
// Button attributes
button: {
// Button text.
// Max length of 32 characters.
// Example: "Yoink Flag"
title: string;
// Action attributes
action: {
// Action type. Must be "launch_frame".
type: 'launch_frame';
// App name
// Max length of 32 characters.
// Example: "Yoink!"
name: string;
// Frame launch URL.
// Max 512 characters.
// Example: "https://yoink.party/"
url: string;
// Splash image URL.
// Max 512 characters.
// Image must be 200x200px and less than 1MB.
// Example: "https://yoink.party/img/splash.png"
splashImageUrl: string;
// Hex color code.
// Example: "#eeeee4"
splashBackgroundColor: string;
};
};
};
```
#### Frame Manifest
The manifest file declares the metadata that is applied to the frame application served from this domain. It also defines triggers that indicate which actions it supports from trigger points like casts and the composer.
Frame should provide a JSON manifest file on their domain at the well known URI `/.well-known/farcaster.json`.
```ts
type FarcasterManifest = {
// Metadata associating the domain with a Farcaster account
accountAssociation: {
// base64url encoded JFS header.
// See FIP: JSON Farcaster Signatures for details on this format.
header: string;
// base64url encoded payload containing a single property `domain`
payload: string;
// base64url encoded signature bytes
signature: string;
};
// Frame configuration
frame: FrameConfig;
// Trigger configuration
triggers?: TriggerConfig[];
};
```
**Domain Account Association**
The account association links the domain to a Farcaster account. The signature must be a signed [JSON Farcaster Signature](https://github.com/farcasterxyz/protocol/discussions/208) from the account's custody address with the following payload:
```ts
{
domain: string;
}
```
The domain in the signed object must match the domain the manifest is served from.
**Frame Config**
```ts
type FrameConfig = {
// Manifest version. Required.
version: '1';
// App name. Required.
// Max length of 32 characters.
// Example: "Yoink!"
name: string;
// Default launch URL. Required.
// Max 512 characters.
// Example: "https://yoink.party/"
homeUrl: string;
// Frame application icon URL.
// Max 512 characters.
// Image must be 200x200px and less than 1MB.
// Example: "https://yoink.party/img/icon.png"
iconUrl: string;
// Default image to show when frame is rendered in a feed.
// Max 512 characters.
// Image must have a 3:2 ratio.
// Example: "https://yoink.party/framesV2/opengraph-image"
imageUrl: string;
// Default button title to use when frame is rendered in a feed.
// Max 32 characters.
// Example: "🚩 Start"
buttonTitle: string;
// Splash image URL.
// Max 512 characters.
// Image must be 200x200px and less than 1MB.
// Example: "https://yoink.party/img/splash.png"
splashImageUrl?: string;
// Hex color code.
// Example: "#eeeee4"
splashBackgroundColor?: string;
// URL to which clients will POST events.
// Max 512 characters.
// Required if the frame application uses notifications.
// Example: "https://yoink.party/webhook"
webhookUrl?: string;
};
```
**Frame Invocation**
Frames may be invoked in the following ways. When invoked, the frame application may receive additional information about the context in which it was launched.
| Type | Description | Context |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| global | Called when the app is invoked from the app launcher or any other unspecified context. Loads the `homeUrl` defined in the frame application manifest. | None |
| embed | Called when the frame is invoked from an embed in a feed or direct cast. Loads the `url` specified in the FrameEmbed metadata. | Cast hash, embed URL, embed type (feed or direct cast), see below |
| notification | Called when a user taps/clicks a frame notification. Loads the `targetUrl` specified in the notification payload. | Notification ID, see below |
**Triggers**
Triggers allow a user to launch into your frame application from different places in a Farcaster client application. These will eventually replace "cast actions" and "composer actions." See [Feature: Triggers](#feature-triggers) in the Appendix for further details.
```ts
type TriggerConfig =
| {
// Type of trigger, either cast or composer. Required.
type: 'cast';
// Unique ID. Required. Reported to the frame.
// Example: "yoink-score"
id: string;
// Handler URL. Required.
// Example: "https://yoink.party/triggers/cast"
url: string;
// Name override. Optional, defaults to FrameConfig.name
// Example: "View Yoink Score"
name?: string;
}
| {
type: 'composer';
id: string;
url: string;
name?: string;
};
```
The frame receives the trigger type and id as context data.
**Frame manifest caching**
Farcaster clients may cache the frame manifest when scraping embeds, but should provide a mechanism for refreshing the manifest file.
#### Frame UI Specifications

**Header**
Clients should render a header above the frame that includes the name and author specified in the manifest. Clients should show the header whenever the app frame is launched.
**Splash Screen**
Clients should show a splash screen as soon as the app is launched. The icon and background must be specified in the frame manifest or embed meta tags. The frame can hide the splash screen once loading is complete.
**Size & Orientation**
A frame should be rendered in a vertical modal. Mobile frame sizes will be dictated by device dimensions while web frame sizes will be set to 424x695px.
### Client SDK API
Frame applications must include a frame SDK JavaScript package to communicate with the parent app. Frames may include it as a bundled package or using a `