Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 56 additions & 142 deletions docs/mini-apps/quickstart/migrate-existing-apps.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ hidden: true
title: Migrate an Existing App
description: Quickly migrate your existing app to a mini app, preview it in Base Build, and publish to the Base app.
---

<Warning>
**Deprecated:** This guide is for the legacy Mini App flow using Farcaster manifests. As of April 9, 2026, the Base App treats all apps as standard web apps.

**For most developers:** Use the [Migrate to a Standard Web App](/mini-apps/quickstart/migrate-to-standard-web-app) guide instead. You only need this legacy flow if you specifically require Farcaster integration (frames, cast actions, etc.).
</Warning>

<Panel>
<iframe
className="w-3/4 aspect-video rounded-xl mx-auto block"
Expand Down Expand Up @@ -74,168 +81,75 @@ Create a file available at `https://www.your-domain.com/.well-known/farcaster.js
<Tabs>
<Tab title="Vanilla JS">
Create the manifest file in your project at `/public/.well-known/farcaster.json`.
</Tab>
ω/Tab>
<Tab title="Next.js">
Create a Next.js route to host your manifest file
```typescript app/.well-known/farcaster.json/route.ts
function withValidProperties(properties: Record<string, undefined | string | string[]>) {
return Object.fromEntries(
Object.entries(properties).filter(([_, value]) => (Array.isArray(value) ? value.length > 0 : !!value))
);
}

export async function GET() {
const URL = process.env.NEXT_PUBLIC_URL as string;
return Response.json(paste_manifest_json_object_here); // see the next step for the manifest_json_object
}
```
Create the manifest file in your project at `/public/.well-known/farcaster.json`.
</Tab>
</Tabs>

</Step>

<Step title="Update the Manifest">
Copy the example manifest below and add it to the file created in the previous step. Update each field in the `miniapp`.

For details on each field, see the [field reference](/mini-apps/features/manifest#field-reference)
The manifest file should contain the following:

### Example Manifest
```json /.well-known/farcaster.json
```json
{
"accountAssociation": { // these will be added in step 5
"header": "",
"payload": "",
"signature": ""
"accountAssociation": {
"header": "eyJmaWQiOjE1Njk0LCJ0eXBlIjoiY3VzdG9keSIsImtleSI6IjB4NTR...",
"payload": "eyJkb21haW4iOiJleGFtcGxlLmNvbSJ9",
"signature": "MHg5ZjI5ZDIzMzUzZjE2Y2Y1ZTVkYjIwN2YxZTBiMzA0..."
},
"miniapp": {
"version": "1",
"name": "Example Mini App",
"homeUrl": "https://ex.co",
"iconUrl": "https://ex.co/i.png",
"splashImageUrl": "https://ex.co/l.png",
"frame": {
"version": "next",
"name": "Example App",
"iconUrl": "https://example.com/icon.png",
"homeUrl": "https://example.com",
"imageUrl": "https://example.com/image.png",
"buttonTitle": "Launch",
"splashImageUrl": "https://example.com/splash.png",
"splashBackgroundColor": "#000000",
"webhookUrl": "https://ex.co/api/webhook",
"subtitle": "Fast, fun, social",
"description": "A fast, fun way to challenge friends in real time.",
"screenshotUrls": [
"https://ex.co/s1.png",
"https://ex.co/s2.png",
"https://ex.co/s3.png"
],
"primaryCategory": "social",
"tags": ["example", "miniapp", "baseapp"],
"heroImageUrl": "https://ex.co/og.png",
"tagline": "Play instantly",
"ogTitle": "Example Mini App",
"ogDescription": "Challenge friends in real time.",
"ogImageUrl": "https://ex.co/og.png",
"noindex": true
"webhookUrl": "https://example.com/api/webhook"
}
}
```
</Step>

<Step title="Create accountAssociation Credentials">
The `accountAssociation` fields in the manifest are used to verify ownership of your app. You can generate these fields on Base Build.


1. Ensure all changes are live so that the Manifest file is available at your app's url.
2. Navigate to the Base Build [Account association tool](https://www.base.dev/preview?tab=account).
3. Paste your domain in the `App URL` field (ex: sample-url.vercel.app) and click "Submit"
4. Click on the "Verify" button that appears and follow the instructions to generate the `accountAssociation` fields.
5. Copy the `accountAssociation` fields and paste them into the manifest file you added in the previous step.
```json /.well-known/farcaster.json
{
"accountAssociation": {
"header": "eyJmaWQiOjkxNTIsInR5cGUiOiJjdXN0b2R5Iiwia2V5IjoiMHgwMmVmNzkwRGQ3OTkzQTM1ZkQ4NDdDMDUzRURkQUU5NDBEMDU1NTk2In0",
"payload": "eyJkb21haW4iOiJhcHAuZXhhbXBsZS5jb20ifQ",
"signature": "MHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAyMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwYzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxNzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEyNDdhNDhlZGJmMTMwZDU0MmIzMWQzZTg1ZDUyOTAwMmEwNDNkMjM5NjZiNWVjNTNmYjhlNzUzZmIyYzc1MWFmNTI4MWFiYTgxY2I5ZDE3NDAyY2YxMzQxOGI2MTcwYzFiODY3OTExZDkxN2UxMzU3MmVkMWIwYzNkYzEyM2Q1ODAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjVmMTk4MDg2YjJkYjE3MjU2NzMxYmM0NTY2NzNiOTZiY2VmMjNmNTFkMWZiYWNkZDdjNDM3OWVmNjU0NjU1NzJmMWQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwOGE3YjIyNzQ3OTcwNjUyMjNhMjI3NzY1NjI2MTc1NzQ2ODZlMmU2NzY1NzQyMjJjMjI2MzY4NjE2YzZjNjU2ZTY3NjUyMjNhMjI2NDJkMzQ0YjMzMzMzNjUyNDY3MDc0MzE0NTYxNjQ2Yjc1NTE0ODU3NDg2ZDc5Mzc1Mzc1Njk2YjQ0MzI0ZjM1NGE2MzRhNjM2YjVhNGM3NDUzMzczODIyMmMyMjZmNzI2OTY3Njk2ZTIyM2EyMjY4NzQ3NDcwNzMzYTJmMmY2YjY1Nzk3MzJlNjM2ZjY5NmU2MjYxNzM2NTJlNjM2ZjZkMjIyYzIyNjM3MjZmNzM3MzRmNzI2OTY3Njk2ZTIyM2E2NjYxNmM3MzY1N2QwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA"
},
"miniapp": {...} // these fields remain the same
}
```
<Info>
Note: Because you are signing with your Base Account, the `signature` field will be significantly longer than if you were to sign directly with your Farcaster custody wallet.
</Info>

To generate the `accountAssociation` fields, use the [Farcaster Account Association tool](https://farcaster.xyz/~/developers/mini-apps/account-association).
</Step>

<Step title="Add Embed Metadata">
Update your index.html file to include the `fc:miniapp` metadata. This is used to generate the rich embeds when your app is shared and is required for your app to display.
<Step title="Verify the Manifest">
Ensure your manifest is accessible at the correct URL:

<Tabs>
<Tab title="Vanilla JS">
Add directly to your index.html file.
```html index.html
<meta name="fc:miniapp" content='{
"version":"next",
"imageUrl":"https://your-app.com/embed-image",
"button":{
"title":"Play Now",
"action":{
"type":"launch_miniapp",
"name":"Your App Name",
"url":"https://your-app.com"
}
}
}' />
```
</Tab>
<Tab title="Next.js">
Use the `generateMetadata` function to add the `fc:miniapp` metadata.
```typescript app/layout.tsx
export async function generateMetadata(): Promise<Metadata> {
return {
other: {
'fc:miniapp': JSON.stringify({
version: 'next',
imageUrl: 'https://your-app.com/embed-image',
button: {
title: `Launch Your App Name`,
action: {
type: 'launch_miniapp',
name: 'Your App Name',
url: 'https://your-app.com',
splashImageUrl: 'https://your-app.com/splash-image',
splashBackgroundColor: '#000000',
},
},
}),
},
};
}
```
</Tab>
</Tabs>
</Step>
<Step title="Push to Production">
Ensure all changes are live.
```
https://www.your-domain.com/.well-known/farcaster.json
```

The file should be publicly accessible and return valid JSON.
</Step>

<Step title="Preview Your App">
Use the Base Build [Preview tool](https://www.base.dev/preview) to validate your app.
1. Add your app URL to view the embeds and click the launch button to verify the app launches as expected.
2. Use the "Account association" tab to verify the association credentials were created correctly.
3. Use the "Metadata" to see the metadata added from the manifest and identify any missing fields.

<video
autoPlay
muted
loop
playsInline
src="/videos/mini-apps/basebuildpreview.mp4"
></video>
<Step title="Register on Base.dev">
1. Go to [Base.dev](https://www.base.dev)
2. Sign in with your account
3. Click "Add Project"
4. Enter your app details and domain
5. Verify ownership (the manifest file helps with this)
</Step>
<Step title="Post to Publish">
To publish your app, create a post in the Base app with your app's URL.

<Step title="Import as Mini App">
After registering on Base.dev:

<img
src="/images/minikit/publish-app-base.png"
alt="Posting an app to Base app"
height="300"
className="rounded-lg"
/>
1. Go to your project dashboard
2. Click "Import Mini App"
3. Enter your domain
4. The system will verify your manifest file
5. Once verified, your app will be available in the Base App
</Step>
</Steps>

---

## Alternative: Standard Web App Flow

If you don't need Farcaster-specific features (frames, cast actions, etc.), consider using the [standard web app flow](/mini-apps/quickstart/migrate-to-standard-web-app) instead. This is the recommended approach for most apps as of April 9, 2026.

The standard web app flow:
- Does not require a Farcaster manifest
- Uses wagmi/viem for wallet connection instead of the MiniApp SDK
- Works with any standard web app
- Is simpler to implement and maintain
Loading