Project type: OnChain Data API

Frames.js - fastest way to build Frames – frames.js
Skip to contentIntroductionGuidesChevron RightCreate a FrameDebuggingMulti-page FramesState ManagementState via Query ParamsDeploying your FrameImage GenerationDynamic ImagesPerformanceVerifying Frame ActionsMiddlewareTransactionsOpen FramesLens SupportXMTP SupportCast ActionsComposer ActionsWallet SignaturesFrames.js for AppsChevron RightDisplay Frames in ReactDisplay Frames in React NativeBest PracticesCLIChevron RightCreating a project from templateWrite your frame withChevron RightNext.jsNext.js (Pages Router)Express.jsHonoRemixCloudflare WorkersMiddlewareChevron RightImages WorkerFarcaster Hub ContextOpen FramesNeynar ValidateTroubleshootingExamplesChevron RightBasicCast ActionsComposer ActionsCustom Font (nodejs)Custom Farcaster HubCustom MiddlewareDynamic ImageError HandlingImages WorkerCustom Images WorkerMint ButtonMulti PageMulti ProtocolOnly Followers Can MintPost RedirectStateState SigningState via Query ParamsTransactionUser DataWallet SignaturesDynamic RoutesReferenceChevron Rightframes.js/coreChevron RightcreateFramesButtonredirecterrortransactionframes.jsChevron RighttypesgetAddressForFidgetFramegetFrameFlattenedgetFrameHtmlgetFrameMessagegetUserDataForFidvalidateFrameMessageXMTPChevron RightTutorialgetXmtpFrameMessageisXmtpFrameActionPayloadLensChevron RightTutorialgetLensFrameMessageisLensFrameActionPayload@frames.js/renderChevron RightuseFrametypesHeadless FrameUIFrameUIIdentityAnonymousFarcasterLensXMTPStorageNext.jsChevron RightFrameImagePOSTGETDeprecated APIsframes.js/next/serverChevron RightgetPreviousFramePOSTframes.js/next/server - [react]Chevron RighttypesFrameContainerFrameButtonFrameImageFrameInputparseFrameParamsuseFramesReducervalidateActionSignaturecreatePreviousFrameSearchGithub 0.19.5
Github this pageChevron Right# frames.js
npmpnpmyarnnpm install frames.js**frames.js** is the fastest way to make Frames.
## What's in frames.js?
* ⚡️ Local frames debugger
* 🥳 Write Frames using React
* 🔋 Batteries included framework
* 🌴 Tree-shakeable & Lightweight
* 🚀 Library with all the functions
## Bootstrap the project from template using the CLI tool
Run one of the commands below based on your preferred package manager and then follow the steps in the terminal.
## Alternatively, add frames.js to your existing project manually
### Start with frames.js in Next.js in three steps
### Add `frames.js` to your project
### Create your Frames app
Create a `frames` directory in your Next.js app and add the following files:
import { createFrames } from "frames.js/next";
export const frames = createFrames({
### Create a Frames route
/* eslint-disable react/jsx-key */
import { Button } from "frames.js/next";
import { frames } from "./frames";
const handleRequest = frames(async (ctx) => {
? `I clicked ${ctx.searchParams.value}`
: `Click some button`}
<Button action="post" target={{ query: { value: "Yes" } }}>
<Button action="post" target={{ query: { value: "No" } }}>
export const GET = handleRequest;
export const POST = handleRequest;
### Include Frames alongside your existing page's metadata
import { fetchMetadata } from "frames.js/next";
export async function generateMetadata() {
// provide a full URL to your /frames endpoint
export default function Page() {
return <span>My existing page</span>;
### Run `yarn run dev`
This will start the development server but when you open the browser you won't see anything except `My existing page`. This is because frames are defined as meta tags therefore you need to use some sort of a client that renders them.
**Please follow our debugging guide so you can easily preview and debug your application.**### Have fun! 🎉
Check out the following places for more Frames-related content:
* Join the /frames-dev channel on Farcaster to ask questions
* Follow Frames.js & team (@df and @stephancill on Farcaster for updates
* Star frames.js on GitHub to show your support and keep track of updates
* Browse the awesome-frames list of awesome Frames projects and resources
## Local fully interactive Debugger & Frame validation
Or use the hosted Frames debugger Running locally has the benefits of it working with natively with localhost.
## Prefer to not use JSX?
### frames.js in Next.js using helper functions
// Page that returns a frame
import { Frame, getFrameFlattened } from "frames.js";
import type { Metadata } from "next";
// Declare the frame
const initialFrame: Frame = {
// Export Next.js metadata
export const metadata: Metadata = {
title: "Random Image Frame",
description: "This is an example of a simple frame using frames.js",
// Route that handles frame actions
import { getFrameHtml, validateFrameMessage } from "frames.js";
import { NextRequest } from "next/server";
export async function POST(request: NextRequest) {
const body = await request.json();
// Parse and validate the frame message
const { isValid, message } = await validateFrameMessage(body);
if (!isValid || !message) {
return new Response("Invalid message", { status: 400 });
const randomInt = Math.floor(Math.random() * 100);
const imageUrlBase = `{randomInt}`;
// Use the frame message to build the frame
const frame = {
label: `Next (pressed by ${message.data.fid})`,
// Return the frame as HTML
const html = getFrameHtml(frame);
return new Response(html, {
The source code for frames.js is available on GitHub 
frames.js is distributed under an MIT License.
We welcome contributions from the community. If you would like to contribute, please open an issue or a pull request.
Feel free to ask any questions on /frames-devs and tag @frames