> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neynar.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Convert a Web App to a Farcaster Mini App

> Update any JavaScript web app to be a Farcaster mini app

<Info>
  If looking to create a new mini app from scratch, see [Create Farcaster Mini App in 60s](/docs/create-farcaster-miniapp-in-60s).
</Info>

Converting an existing JavaScript-based web app to a Farcaster mini app involves the following steps:

* install the <a href="https://www.npmjs.com/package/@neynar/react" target="_blank" rel="noopener noreferrer nofollow">@neynar/react</a> npm package and use the `<MiniAppProvider>` provider in your app
  * alternatively, install the
    <a href="https://www.npmjs.com/package/@farcaster/miniapp-sdk" target="_blank" rel="noopener noreferrer nofollow">Mini App SDK</a> and call `sdk.actions.ready()`
* integrate with the SDK's ethereum provider exposed via `sdk.wallet.ethProvider`
* add a `farcaster.json` file with mini app metadata and a signature proving ownership
* add a custom HTML `<meta />` tag specifying how embeds should be rendered

## Installing the SDK

### Using @neynar/react

The recommended way to integrate your app with Farcaster is using the `@neynar/react` package, which includes the Mini App SDK along with custom Neynar components and built-in analytics:

```bash theme={"system"}
npm install @neynar/react
```

Then wrap your app with the `<MiniAppProvider>` provider:

```javascript theme={"system"}
import { MiniAppProvider } from '@neynar/react';

export default function App() {
  return (
    <MiniAppProvider analyticsEnabled={true}>
      {/* Your app components */}
    </MiniAppProvider>
  );
}
```

With the MiniAppProvider provider in place, you can access Mini App SDK functionality with the `useMiniApp()` react hook:

```javascript theme={"system"}
import { useMiniApp } from '@neynar/react';

export default function HomePage() {
  const { isSDKLoaded, context } = useMiniApp();
  return (<>
    {isSDKLoaded && (
      <div>{context}</div>
    )}
  </>)
}
```

### Using the Mini App SDK

Alternatively, you can use the Mini App SDK (formerly the Frame SDK):

```bash theme={"system"}
npm install @farcaster/miniapp-sdk
```

Then call the ready function when your interface is loaded and ready to be displayed:

```javascript theme={"system"}
import { sdk } from '@farcaster/miniapp-sdk';
 
await sdk.actions.ready();
```

You should call `ready()` as early as possible in the app, but after any pageload processes that might cause the UI to re-render or update significantly. In a React app, it's generally best to call `ready()` inside the page-level component at the root of your UI, e.g. in your homepage component.

Here's an example of how you might do this in a standard React app:

```javascript {9} theme={"system"}
import { useEffect, useState } from "react";
import { sdk } from '@farcaster/miniapp-sdk';

export default function Home() {
  const [isLoaded, setIsLoaded] = useState(false);

  useEffect(() => {
    const load = async () => {
      await sdk.actions.ready();
      setIsLoaded(true);
    };
    if (sdk && !isLoaded) {
      load();
    }
  }, [isLoaded]);

  return (...)
}
```

## Connecting to the wallet provider

It's recommended to use `wagmi` for your wallet provider, as the Farcaster team provides the
<a href="https://www.npmjs.com/package/@farcaster/miniapp-wagmi-connector" target="_blank" rel="noopener noreferrer nofollow">@farcaster/miniapp-wagmi-connector package</a> for easy configuration.

Run `npm i @farcaster/miniapp-wagmi-connector` to install, and then connecting is as simple as adding the connector to the wagmi config:

```javascript {11} theme={"system"}
import { http, createConfig } from 'wagmi';
import { base } from 'wagmi/chains';
import { farcasterMiniApp } from '@farcaster/miniapp-wagmi-connector';
 
export const wagmiConfig = createConfig({
  chains: [base],
  transports: {
    [base.id]: http(),
  },
  connectors: [
    farcasterMiniApp()
    // add other wallet connectors like metamask or coinbase wallet if desired
  ]
});
```

With the above configuration, you can access the mini app user's connected wallet with normal wagmi hooks like `useAccount()`.

## Connecting to Solana

For Solana support, install the package and wrap your app with the Solana provider:

<CodeGroup>
  ```bash Bash theme={"system"}
  npm install @farcaster/mini-app-solana
  ```
</CodeGroup>

<CodeGroup>
  ```typescript App.tsx theme={"system"}
  import { FarcasterSolanaProvider } from '@farcaster/mini-app-solana';

  function App() {
    const solanaEndpoint = 'https://solana-rpc.publicnode.com';
    
    return (
      <FarcasterSolanaProvider endpoint={solanaEndpoint}>
        {/* Your app components */}
      </FarcasterSolanaProvider>
    );
  }
  ```
</CodeGroup>

Use Solana wallet hooks in your components:

<CodeGroup>
  ```typescript SolanaExample.tsx theme={"system"}
  import { useSolanaConnection, useSolanaWallet } from '@farcaster/mini-app-solana';
  import { Transaction, SystemProgram, PublicKey } from '@solana/web3.js';

  function SolanaExample() {
    const { publicKey, signMessage, sendTransaction } = useSolanaWallet();
    const { connection } = useSolanaConnection();

    const handleSign = async () => {
      if (!signMessage) return;
      const message = new TextEncoder().encode("Hello Solana!");
      const signature = await signMessage(message);
      console.log('Signed:', btoa(String.fromCharCode(...signature)));
    };

    const handleSend = async () => {
      if (!publicKey || !sendTransaction) return;
      
      const { blockhash } = await connection.getLatestBlockhash();
      const transaction = new Transaction();
      transaction.add(
        SystemProgram.transfer({
          fromPubkey: publicKey,
          toPubkey: new PublicKey('DESTINATION_ADDRESS'),
          lamports: 1000000, // 0.001 SOL
        })
      );
      transaction.recentBlockhash = blockhash;
      transaction.feePayer = publicKey;

      const signature = await sendTransaction(transaction, connection);
      console.log('Transaction:', signature);
    };

    return (
      <div>
        <button onClick={handleSign}>Sign Message</button>
        <button onClick={handleSend}>Send SOL</button>
      </div>
    );
  }
  ```
</CodeGroup>

<Info>
  The Solana provider will only be available when the user's wallet supports Solana. Always check `hasSolanaProvider` before rendering Solana-specific UI components.
</Info>

## Adding and signing the farcaster.json file

Mini apps are expected to serve a farcaster.json file, also known as a "manifest", at `/.well-known/farcaster.json`, published at the root of the mini app's domain.

The manifest consists of a `miniapp` section containing metadata specific to the mini app and an `accountAssociation` section consisting of a JSON Farcaster Signature (JFS) to verify ownership of the domain and mini app.

The `miniapp` metadata object only has four required fields (`version`, `name`, `homeUrl`, and `iconUrl`), but providing more is generally better to help users and clients discover your mini app. See the full list of options [here in the Farcaster docs](https://miniapps.farcaster.xyz/docs/specification#frame).

Start by publishing just the miniapp portion of the manifest:

```json theme={"system"}
{
  "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",
    "webhookUrl": "https://yoink.party/api/webhook"
  }
}
```

In a standard react app, you can do this by placing a JSON file in your public folder, to be served as a static file:

```
public/
├── .well-known/
    └── farcaster.json
```

Once your domain is live and serving something like the above example at `yourURL.com/.well-known/farcaster.json`, you need to generate an `accountAssociation` signed with your farcaster custody address:

* go to <a href="https://farcaster.xyz/~/developers/mini-apps/manifest" target="_blank" rel="noopener noreferrer nofollow">the Mini App Manifest Tool</a>
  in your desktop browser
* enter your domain and scroll to the bottom
* click "Claim Ownership", and follow the steps to sign the manifest with your Farcaster custody address using your phone
* finally, copy the output manifest from the manifest tool and update your domain to serve the full, signed farcaster.json file, which should look something like this:

```json theme={"system"}
{
  "accountAssociation": {
    "header": "eyJmaWQiOjM2MjEsInR5cGUiOiJjdXN0b2R5Iiwia2V5IjoiMHgyY2Q4NWEwOTMyNjFmNTkyNzA4MDRBNkVBNjk3Q2VBNENlQkVjYWZFIn0",
    "payload": "eyJkb21haW4iOiJ5b2luay5wYXJ0eSJ9",
    "signature": "MHgwZmJiYWIwODg3YTU2MDFiNDU3MzVkOTQ5MDRjM2Y1NGUxMzVhZTQxOGEzMWQ5ODNhODAzZmZlYWNlZWMyZDYzNWY4ZTFjYWU4M2NhNTAwOTMzM2FmMTc1NDlmMDY2YTVlOWUwNTljNmZiNDUxMzg0Njk1NzBhODNiNjcyZWJjZTFi"
  },
  "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",
    "webhookUrl": "https://yoink.party/api/webhook"
  }
}
```

## Configuring embed metadata

To allow your mini app to render properly in social feeds, you must add a meta tag with the name "fc:frame" to the `<head>` section of the HTML page serving your mini app.

```html theme={"system"}
<meta name="fc:frame" content="<stringified Embed JSON>" />
```

The full schema can be found [here in the Farcaster docs](https://miniapps.farcaster.xyz/docs/specification#schema), but the most common button action is `launch_miniapp`, so unless you have a specific use case, you can safely copy the following example:

```json theme={"system"}
{
  "version": "next",
  "imageUrl": "https://yoink.party/framesV2/opengraph-image",
  "button": {
    "title": "🚩 Start",
    "action": {
      "type": "launch_miniapp",
      "name": "Yoink!",
      "url": "https://yoink.party/framesV2",
      "splashImageUrl": "https://yoink.party/logo.png",
      "splashBackgroundColor": "#f5f0ec"
    }
  }
}
```
