🥞PancakeJS

Installation

Pancake consists of two main packages: @pancake-apps/server for the backend and @pancake-apps/web for the frontend.

The fastest way to get started is with the CLI:

npx create-pancake my-app
cd my-app
pnpm install
pnpm dev

This sets up everything you need with sensible defaults.

Manual Installation

If you prefer to set up manually or add Pancake to an existing project:

# Core packages
pnpm add @pancake-apps/server @pancake-apps/web

# Required dependencies
pnpm add express zod

# Dev dependencies
pnpm add -D typescript @types/node tsx
# Core packages
npm install @pancake-apps/server @pancake-apps/web

# Required dependencies
npm install express zod

# Dev dependencies
npm install -D typescript @types/node tsx
# Core packages
yarn add @pancake-apps/server @pancake-apps/web

# Required dependencies
yarn add express zod

# Dev dependencies
yarn add -D typescript @types/node tsx

For React Views

If you want React components with hot reload:

pnpm add react react-dom
pnpm add -D @types/react @types/react-dom @vitejs/plugin-react vite
npm install react react-dom
npm install -D @types/react @types/react-dom @vitejs/plugin-react vite
yarn add react react-dom
yarn add -D @types/react @types/react-dom @vitejs/plugin-react vite

Package Overview

PackageDescription
@pancake-apps/serverServer framework for views, actions, data, and MCP/OpenAI adapters
@pancake-apps/webClient SDK with React hooks and protocol adapters

TypeScript Configuration

Create or update your tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "strict": true,
    "jsx": "react-jsx",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "declaration": true,
    "outDir": "./dist"
  },
  "include": ["src"]
}

Minimal Server Setup

Create src/index.ts:

import { createApp, defineView } from '@pancake-apps/server';
import { z } from 'zod';

const app = createApp({
  name: 'my-app',
  version: '0.1.0',

  views: {
    hello: defineView({
      description: 'A greeting view',
      input: z.object({ name: z.string().optional() }),
      data: z.object({ greeting: z.string() }),
      handler: async ({ name }) => ({
        greeting: `Hello ${name || 'World'}!`,
      }),
      ui: { html: './src/views/hello.html' },
    }),
  },
});

app.start({ port: 3000 });

Create src/views/hello.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Hello View</title>
  <style>
    body { font-family: system-ui; padding: 2rem; }
  </style>
</head>
<body>
  <h1 id="greeting">Loading...</h1>
  <script type="module">
    const waitForPancake = () => new Promise((resolve) => {
      if (window.pancake) return resolve(window.pancake);
      const check = setInterval(() => {
        if (window.pancake) {
          clearInterval(check);
          resolve(window.pancake);
        }
      }, 50);
    });

    const pancake = await waitForPancake();
    const data = pancake.adaptor.getToolOutput();
    document.getElementById('greeting').textContent = data?.greeting || 'Hello!';
  </script>
</body>
</html>

Verify Installation

Run your server:

npx tsx src/index.ts

Test the MCP endpoint:

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

You should see your view listed as a tool.

You're set up! Check the Getting Started guide for a complete walkthrough.

Next Steps

On this page