> ## Documentation Index
> Fetch the complete documentation index at: https://base-a060aa97-eb-mini-app-ia-overhaul.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Mini Apps in Base App

> Guide for building and optimizing mini apps for Base App

We're so excited that mini apps are supported in Base App! The purpose of this guide is to go over how to build or update your mini app so it works as well as possible in Base App.

## Using MiniKit

For reference, MiniKit is easiest way to build mini apps on Base, allowing developers to easily build mini apps without needing to know the details of the SDK implementation. It integrates seamlessly with OnchainKit components and provides Base App-specific hooks.

<Card title="Quick Start with MiniKit" icon="rocket" href="/base-app/build-with-minikit/quickstart">
  If you use MiniKit and/or follow the MiniKit quickstart guide, your mini app will work out of the box in Base App!
</Card>

<Card title="Debugging Guide" icon="bug" href="/base-app/build-with-minikit/debugging">
  If you're already using MiniKit and experiencing issues, you can refer to our debugging guide
</Card>

## Authentication

<Warning>
  As a general rule of thumb, we recommend that you save authentication that requires an interaction for interactions that require it(eg. buying something, viewing personalized pages etc)
</Warning>

Below we will quickly cover the different methods of authentication offered for mini apps and how well each of them work in Base App:

<Tabs>
  <Tab title="Sign In with Farcaster/Quick Auth">
    Base App natively supports [Sign In with Farcaster](https://github.com/farcasterxyz/protocol/discussions/110)(SIWF) in-app, so you can sign users in and get their social identity all without leaving Base App.

    We also support [Quick Auth](https://miniapps.farcaster.xyz/docs/sdk/quick-auth), which uses Sign In with Farcaster to issue developers a  [JWT](https://jwt.io/introduction) that can be used to persist the user's session in the mini app.

    This is the expected flow for end-users to Sign In with Farcaster in your mini app:

    * **Create Account Users**: Users who created a net-new Farcaster account during Base App onboarding
      * When signing into a mini app, the user will be prompted to see a "Login request" tray showing the SIWF message and can sign it right their with their passkey
    * **Connect Account Users**: Users who connected an existing Farcaster account during Base App onboarding
      * When signing into a mini app for the first time, the user will be prompted to deeplink to Farcaster(one-time only) and register their wallet as an auth address, which will then enable seamless in-app sign in -- just like the above create account flow
  </Tab>

  <Tab title="Wallet Auth">
    Because users in Base App have an in-app smart wallet that doesn't require any app switching, we recommend wallet authentication as the primary method of authentication for developers looking to create a persisted session for the mini app user.

    As described below, we don't think it's the best practice to prompt the user to log in before that authentication will allow them to do something else in your mini app, but for cases where do you want a secure, persisted session, using a wallet connection is a great option.
  </Tab>

  <Tab title="Context Data">
    All mini app host apps (including Base App) return [context data](https://miniapps.farcaster.xyz/docs/sdk/context), which tells developers about the app/mini app host the user is accessing their mini app in, as well as **which user** is interacting with their mini app.

    A common flow that other mini app developers follow is using the context data to either track analytics metrics or create an authentication session via a [JWT](https://jwt.io/introduction). This allows you to still track analytics/offer certain authenticated services to your users without the extra friction of signing a message or deeplinking to another app.

    <Warning>
      Something important to note is that because of how the current mini app spec is written, context data can technically be spoofed by any developer who makes their own mini app host. Because of this, we recommend that context data is not used as the **primary** method of authentication.
    </Warning>
  </Tab>
</Tabs>

## Deeplinks and SDK Actions

The official mini apps SDK offers a [set of actions](https://miniapps.farcaster.xyz/docs/specification#actions) (which MiniKit offers as well) so that users of your mini app can be led to do things back in clients like Base App (e.g. compose a cast, view a profile, etc).

<Warning>
  **Always use official SDK functions instead of Farcaster-specific deeplinks in your mini app.**
</Warning>

While some developers have used Farcaster-specific deeplinks in the `openUrl` function as a workaround, this approach can create problems. Farcaster-specific deeplinks might not match Base App-specific deeplinks, **potentially leaving users dead-ended and unable to take further action in your mini app**.

Using the official SDK functions ensures your users have the best viewing experience possible across all supported clients, including Base App.

## Wallet Interactions

Wallet interactions are a core part of the miniapp experience. We want to ensure both that building wallet interactions on top of the Base App is smooth for developers and that users can choose/have funds sent to their Base App when interacting with mini apps.

As a mini app host, we expose an [EIP-1193 Ethereum Provider](https://eips.ethereum.org/EIPS/eip-1193) that can be accessed in two primary ways:

<Tabs>
  <Tab title="OnchainKit Wallet Component (Recommended)">
    By using the [Wallet](https://docs.base.org/builderkits/onchainkit/wallet/wallet) component offered in OnchainKit/MiniKit

    <Note>
      If you run `npm create onchain --mini`, your mini app will have a "Connect Wallet" button already set up
    </Note>
  </Tab>

  <Tab title="Wagmi">
    [Wagmi](https://wagmi.sh) is a powerful JavaScript library for building Ethereum applications, and using it alongside any other onchain logic you have configured is very simple.
    It only takes the two steps below to auto-connect to the user's wallet with Wagmi:

    1. Set up your WagmiProvider to use the Farcaster mini app connector

    ```javascript
    import { createConfig, http, WagmiProvider } from "wagmi";
    import { base } from "wagmi/chains";
    import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
    import { farcasterFrame } from "@farcaster/frame-wagmi-connector";

    export const config = createConfig({
      chains: [base],
      transports: {
        [base.id]: http()
      },
      connectors: [farcasterFrame()],
    });

    const queryClient = new QueryClient();

    export default function Provider({ children }: { children: React.ReactNode }) {
      return (
        <WagmiProvider config={config}>
          <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
        </WagmiProvider>
      );
    }
    ```

    2. Listen for and use the auto-connected wallet session, if not connect the user

    ```javascript
    "use client";

    import { useAccount, useConnect, useDisconnect } from "wagmi";
    import { config } from "~/components/providers/WagmiProvider";

    export function WalletConnectMinimal() {
      const { address, isConnected } = useAccount();
      const { connect } = useConnect();
      const { disconnect } = useDisconnect();

      return (
        <button onClick={() => 
          isConnected 
            ? disconnect() 
            : connect({ connector: config.connectors[0] })}>
          {isConnected ? "Disconnect" : "Connect"}
        </button>
      );
    }
    ```
  </Tab>

  <Tab title="Browser Window">
    Because of the open standards this is built on top of, you can both listen for and connect to our injected wallet provider without installing any new package, directly from the browser window's DOM! There are two ways to do this that are both highlighted below:

    Connect directly with `window.ethereum`

    ```javascript
    // Check if provider exists  
    if (window.ethereum) {  
      // Use the provider directly  
      const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });  
      const chainId = await window.ethereum.request({ method: 'eth_chainId' });  
    }
    ```

    Use EIP-6963 discovery to listen for the provider's injection

    ```javascript
    // Listen for provider announcements  
    window.addEventListener('eip6963:announceProvider', (event) => {  
      const provider = event.detail.provider;  
      // Use the provider  
    });  
      
    // Request providers  
    window.dispatchEvent(new Event('eip6963:requestProvider'));
    ```
  </Tab>
</Tabs>

## Metadata

Farcaster has recently [extended the metadata spec for mini apps](https://github.com/farcasterxyz/miniapps/discussions/191), which allows developers to add screenshot links, categories, and more to their manifest (farcaster.json) file. Making use of these new metadata fields is highly recommended for increasing the chance that your mini app could be featured throughout Base App.

Below is a table of the new metadata fields introduced, what they mean/could potentially be used for, and an example of what a manifest file could look like with these new fields (all taken from the [official spec](https://github.com/farcasterxyz/miniapps/discussions/191))

<Info>
  Note: We **highly recommend** that you set this metadata as it will give your mini app a better shot at being featured throughout Base App.
</Info>

<AccordionGroup>
  <Accordion title="Mini App Store Listing">
    | Field      | Purpose                              | Limitations                                    | Design Guidelines                                                                 |
    | ---------- | ------------------------------------ | ---------------------------------------------- | --------------------------------------------------------------------------------- |
    | `iconUrl`  | Main icon                            | 1024x1024 px PNG, no alpha                     | Use a bold, recognizable logo. No text. Avoid photos or screenshots.              |
    | `name`     | Display name of the app              | 30 characters, no emojis or special characters | Use brandable, unique names. Avoid generic terms. No emojis or trademark symbols. |
    | `subtitle` | Short description under the app name | 30 characters, no emojis or special characters | Should clarify what your app does in a catchy way. Avoid repeating the title.     |
  </Accordion>

  <Accordion title="Mini App Store Page">
    | Field            | Purpose                                        | Limitations                                     | Design Guidelines                                                                                                                |
    | ---------------- | ---------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
    | `description`    | Promotional message displayed on Mini App Page | 170 characters, no emojis or special characters | Use short paragraphs, headings, and bullet points. Focus on value, not features. Include social proof if possible. Avoid jargon. |
    | `screenshotUrls` | Visual previews of the app, max 3 screens      | Portrait, 1284 x 2778                           | Focus on showing the core value or magic moment of the app in the first 2–3 shots. Use device frames and short captions.         |
  </Accordion>

  <Accordion title="Search & Discovery">
    | Field             | Purpose                               | Options                                                                                                                                                                                 | Design Guidelines                                                                    |
    | ----------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
    | `primaryCategory` | Primary category of app               | One of: `games`, `social`, `finance`, `utility`, `productivity`, `health-fitness`, `news-media`, `music`, `shopping`, `education`, `developer-tools`, `entertainment`, `art-creativity` | Choose the category that best represents your app's primary use case                 |
    | `tags`            | Descriptive tags for filtering/search | up to 5 tags                                                                                                                                                                            | Use 3–5 high-volume terms; no spaces, no repeats, no brand names. Use singular form. |
  </Accordion>

  <Accordion title="Promotional Assets">
    | Field          | Purpose                                                | Limitations           | Design Guidelines                                                                                               |
    | -------------- | ------------------------------------------------------ | --------------------- | --------------------------------------------------------------------------------------------------------------- |
    | `heroImageUrl` | Promotional display image on top of the mini app store | 1200 x 630px (1.91:1) | 1200x630 px JPG or PNG. Should show your brand clearly. No excessive text. Logo + tagline + UI is a good combo. |
    | `tagline`      | Marketing tagline should be punchy and descriptive     | 30 characters         | Use for time-sensitive promos or CTAs. Keep copy active (e.g., "Grow, Raid & Rise in Stoke Fire").              |
  </Accordion>

  <Accordion title="Sharing Experience">
    | Field           | Purpose                                    | Limitations           | Design Guidelines                                                                         |
    | --------------- | ------------------------------------------ | --------------------- | ----------------------------------------------------------------------------------------- |
    | `ogTitle`       | Open Graph title for social sharing        | 30 characters         | Use your app name + short tag (e.g., "AppName – Local News Fast"). Title case, no emojis. |
    | `ogDescription` | Open Graph description for social sharing  | 100 characters        | Summarize core benefit in 1–2 lines. Avoid repeating OG title.                            |
    | `ogImageUrl`    | Promotional image (same as app hero image) | 1200 x 630px (1.91:1) | Same as heroImageUrl                                                                      |
  </Accordion>
</AccordionGroup>

### Example Manifest

```json
{
  "accountAssociation": {
    "header": "eyJmaWQiOjkxNTIsInR5cGUiOiJjdXN0b2R5Iiwia2V5IjoiMHgwMmVmNzkwRGQ3OTkzQTM1ZkQ4NDdDMDUzRURkQUU5NDBEMDU1NTk2In0",
    "payload": "eyJkb21haW4iOiJyZXdhcmRzLndhcnBjYXN0LmNvbSJ9",
    "signature": "MHgxMGQwZGU4ZGYwZDUwZTdmMGIxN2YxMTU2NDI1MjRmZTY0MTUyZGU4ZGU1MWU0MThiYjU4ZjVmZmQxYjRjNDBiNGVlZTRhNDcwNmVmNjhlMzQ0ZGQ5MDBkYmQyMmNlMmVlZGY5ZGQ0N2JlNWRmNzMwYzUxNjE4OWVjZDJjY2Y0MDFj"
  },
  "frame": {
    "version": "1",
    "name": "Example Mini App",
    "iconUrl": "https://example.com/app.png",
    "splashImageUrl": "https://example.com/logo.png",
    "splashBackgroundColor": "#000000",
    "homeUrl": "https://example.com",
    "webhookUrl": "https://example.com/api/webhook",
    "subtitle": "Example Mini App subtitle",
    "description": "Example Mini App subtitle",
    "screenshotUrls": [
      "https://example.com/screenshot1.png",
      "https://example.com/screenshot2.png",
      "https://example.com/screenshot3.png"
    ],
    "primaryCategory": "social",
    "tags": [
      "example",
      "mini app",
      "Base App"
    ],
    "heroImageUrl": "https://example.com/og.png",
    "tagline": "Example Mini App tagline",
    "ogTitle": "Example Mini App",
    "ogDescription": "Example Mini App description",
    "ogImageUrl": "https://example.com/og.png"
    // use only while testing
    "noindex": true
  }
}
```

<Warning>
  While testing your Mini App, add "noindex": true to your manifest this prevents the app from being indexed during development.
</Warning>

## Notifications

You will soon be able to send notifications from your Mini App that will appear in Base App. These notifications help re-engage users when something important happens, like a new drop, an update, or a reminder to complete an action. There are two ways to integrate:

<Tabs>
  <Tab title="Use Neynar (Recommended)">
    The fastest way to start sending notifications. Neynar provides:

    * A hosted webhook interface
    * Built-in user token management (opt-in / opt-out)
    * CLI tools and a dashboard
    * Analytics out of the box

    <Card title="Get Started with Neynar" icon="rocket" href="https://docs.neynar.com/docs/send-notifications-to-mini-app-users">
      Learn how to integrate notifications using Neynar
    </Card>
  </Tab>

  <Tab title="Use Your Own Infrastructure">
    You can self-host your own backend as long as it follows the [Farcaster Mini App notification spec](https://miniapps.farcaster.xyz/docs/guides/notifications). This includes:

    * Sending lifecycle events (`notification_enabled`, `notification_disabled`)
    * Posting events to the expected format
  </Tab>
</Tabs>

## Mini Apps Compatibility in Base App

Base App is working towards full compatibility with the Farcaster Mini App SDK. While we continue to enhance support during the beta phase, there are currently some features that are not yet supported.

### AI-Powered Compatibility Checking

We provide a [validate.txt](https://raw.githubusercontent.com/base/demos/refs/heads/master/minikit/mini-app-help/validate.txt) file that can be used with AI tools to automatically check your codebase for Base App compatibility issues. Similar to llms.txt files, you can provide this validation file to language models to scan your Mini App code and receive a detailed compatibility report highlighting any unsupported features or patterns.

<Warning>
  This AI validation is experimental and should only be used in a read-only capacity for analysis and reporting purposes.
</Warning>

### Currently Unsupported Features

The following Mini App SDK features are **not currently supported** in Base App:

#### Environment Detection (ETA 8/6)

* `sdk.isInMiniApp()`

#### Haptic Feedback (ETA 8/13)

* All haptic related SDK methods
  * `sdk.haptics.impactOccurred()`
  * `sdk.haptics.notificationOccurred()`
  * `sdk.haptics.selectionChanged()`

#### Token Actions (ETA 8/6)

* `sdk.actions.swapToken()`

### Wallet Interactions

* `sdk.actions.getEthereumProvider()`
  * Note: We still expose an [EIP-1193 Ethereum Provider](https://eips.ethereum.org/EIPS/eip-1193) that you can auto-detect or use in a package such as MiniKit/Wagmi

#### Navigation & Links

* Direct HTML links to third-party websites (`<a href=`, `<Link href=`)
  * Note: You can instead use `sdk.actions.openUrl()` to safely open a third-party website in our in-app browser
* Warpcast/Farcaster composer intent URLs (`warpcast.com/~/compose`, `farcaster.com/~/compose`)
  * Note: You can instead use `sdk.actions.composeCast()` to compose a cast directly in Base App

#### Notifications are not yet supported

#### Mini App Actions Not Supported (ETA 8/13)

* .addMiniApp()
* .requestCameraAndMicrophoneAccess()

#### Context Features

* Share extensions

#### Supported Chains

* Base
* Mainnet
* Optimism
* Arbitrum
* Polygon
* Zora
* BNB
* Avalanche C-Chain

### Development Notes

* Use `sdk.actions.openUrl()` for external navigation instead of direct HTML links
* Use `sdk.actions.composeCast()` instead of Warpcast composer URLs
* Implement visual feedback alternatives for haptic feedback
* Avoid relying on location context for core functionality
* To conditionally render functionality based on the user's client, check `context.client.clientFid` (Base App returns `309857`)

We are actively working to expand compatibility and expect to support additional features in future releases.
