🥞PancakeJS

Deployment Overview

PancakeJS applications can be deployed anywhere that runs Node.js or supports serverless functions.

Build for Production

# Build all packages
pnpm universal-apps build

This generates:

  • Server bundle ready for Node.js
  • Widget HTML files in dist/widgets/

Directory Structure After Build

dist/
├── server/
│   └── index.js      # Compiled server
└── widgets/
    ├── widget1.html  # Standalone widget HTML
    └── widget2.html

Deployment Options

☁️ Cloudflare Workers

Edge-first deployment with global distribution. Recommended for best latency.

▲ Vercel

Zero-config deployment for Next.js applications.

🚂 Railway

Simple container deployments with automatic SSL.

🐳 Docker

Self-hosted deployments on any infrastructure.

Node.js Server

Deploy to any Node.js hosting:

# Start production server
pnpm universal-apps start --port 8080

Recommended platforms:

  • Railway
  • Render
  • Fly.io
  • DigitalOcean App Platform
  • AWS ECS/Fargate

Serverless Functions

Adapt for serverless with minor changes:

// For Vercel/AWS Lambda
export default async function handler(req, res) {
  const runtime = app.getRuntime();
  const result = await runtime.executeToolCall(
    req.body.tool,
    req.body.input
  );
  res.json(result);
}

Docker

FROM node:20-alpine

WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile --prod

COPY dist ./dist

EXPOSE 3000
CMD ["node", "dist/server/index.js"]

Widget Hosting

Widgets are standalone HTML files that can be served from:

  • Cloudflare Pages
  • Vercel
  • Netlify
  • AWS S3 + CloudFront
# Upload dist/widgets to your CDN
aws s3 sync dist/widgets s3://my-bucket/widgets/

Same Server

Serve widgets from your main server:

app.listen({
  port: 3000,
  dev: false,
  // Widgets served from dist/widgets by default
});

Environment Configuration

Production Config

Create universal-apps.config.ts:

export default {
  widgets: {
    outDir: 'dist/widgets',
  },
  csp: {
    connectDomains: ['api.production.com', 'analytics.example.com'],
    imgDomains: ['images.cdn.com'],
  },
};

Environment Variables

# .env
PORT=8080
NODE_ENV=production
WIDGET_BASE_URL=https://widgets.myapp.com

CSP Configuration

Production widgets should have strict CSP:

app.widget(
  {
    name: 'myWidget',
    ui: {
      entry: 'src/widgets/my.tsx',
      csp: {
        connectDomains: ['api.myapp.com'],
        imgDomains: ['images.myapp.com'],
        scriptDomains: [],   // No external scripts
        styleDomains: [],    // No external styles
      },
    },
  },
  handler
);

Health Checks

Add a health endpoint for monitoring:

app.tool(
  {
    name: '_health',
    description: 'Health check endpoint',
  },
  async () => textResult('OK')
);

Security Checklist

  • ☐ Enable HTTPS
  • ☐ Configure strict CSP
  • ☐ Validate all inputs (Zod schemas)
  • ☐ Rate limit API endpoints
  • ☐ Audit dependencies regularly
  • ☐ Enable logging and monitoring
  • ☐ Set up error alerting

Next Steps

We recommend starting with Cloudflare Workers for the best performance and developer experience.

On this page