Skip to content

Denis-hamon/frame

Repository files navigation

FRAME

AI-powered collaborative presentation builder — think Figma canvas meets Google Slides, with live data connectors and Claude-generated insights.

FRAME Editor

Live demo → · Register for free · No credit card required


Features

Canvas Editor

  • Drag-and-drop elements — text, shapes, images, charts, arrows
  • Real-time collaboration via Yjs CRDT — multiple users, live cursors, zero conflict
  • Undo/redo with Yjs UndoManager (Cmd+Z / Cmd+Shift+Z)
  • Rubber-band multi-select, snap-to-element guides, aspect-ratio lock (Shift+resize)
  • Keyboard shortcuts: Delete, Arrow nudge (1px / 10px with Shift), Cmd+D duplicate, Escape

Data & Charts

  • CSV, Salesforce, BigQuery data connectors — live data bound to chart elements
  • ECharts-powered charts: bar, line, area, pie, scatter
  • Stale-data badges with one-click refresh
  • Filter & query your data directly in the slide panel

AI Insights (Claude)

  • Per-slide AI analysis powered by claude-haiku-4-5
  • Chart-aware insights that understand your data
  • Streaming responses with cancel support
  • Verify insight freshness — stale detection when data changes

Presentation Mode

  • Fullscreen slides with keyboard navigation
  • Speaker notes panel (toggle on/off)
  • Auto-refresh slides from live data sources during presentation

Export

  • PDF export via Puppeteer (async, background job)
  • PPTX export via pptxgenjs
  • Download token system — no auth required for downloads
  • Export status polling with toast notifications

Collaboration & Sharing

  • Workspaces with OWNER / EDITOR / VIEWER roles
  • Email invitations to workspaces
  • Public share links with configurable roles and expiry
  • Share view is read-only, with insight generation support

Stack

Layer Tech
Framework Next.js 16 App Router, TypeScript
Styling Tailwind CSS v4, shadcn/ui (base-ui v3)
Real-time Yjs CRDT, y-websocket v2
State Zustand v5
Charts ECharts v6
AI Anthropic SDK, claude-haiku-4-5
Database PostgreSQL, Prisma 7 (driver adapters)
Auth NextAuth 4, bcryptjs
Exports Puppeteer (PDF), pptxgenjs (PPTX)
Tests Vitest

Quick Start

Prerequisites

1. Clone & install

git clone https://github.com/FRAME-Project/frame.git
cd frame
npm install

2. Start PostgreSQL

With Docker:

docker compose up -d postgres

Or set up manually:

CREATE USER frame_user WITH PASSWORD 'frame_pass123';
CREATE DATABASE frame_db OWNER frame_user;

3. Configure environment

cp .env.example .env.local

Edit .env.local:

DATABASE_URL="postgresql://frame_user:frame_pass123@localhost:5432/frame_db"
NEXTAUTH_SECRET="your-random-secret-here"     # openssl rand -base64 32
NEXTAUTH_URL="http://localhost:3000"
ANTHROPIC_API_KEY="sk-ant-..."

Generate a secret:

openssl rand -base64 32

4. Run database migrations

npx prisma migrate deploy
# or for a fresh dev setup:
npx prisma db push

5. Start the app

# Terminal 1 — Yjs WebSocket server (real-time collaboration)
npm run ws

# Terminal 2 — Next.js dev server
npm run dev

Open http://localhost:3000, register an account, and start building.


Production Deployment

Build

npm run build

On low-RAM machines (< 2GB): NODE_OPTIONS="--max-old-space-size=1536" npm run build

Run

# WebSocket server (background)
npm run ws &

# Next.js production server
npm start

Environment variables for production

Variable Required Description
DATABASE_URL Yes PostgreSQL connection string
NEXTAUTH_SECRET Yes Random 32-byte secret
NEXTAUTH_URL Yes Public URL of the app (e.g. https://frame.example.com)
ANTHROPIC_API_KEY Yes Anthropic API key for AI insights
NEXT_PUBLIC_YJS_WS_URL No WebSocket server URL (default: ws://localhost:1234)
YJS_WS_PORT No WebSocket server port (default: 1234)

NEXT_PUBLIC_YJS_WS_URL must point to your public WebSocket server. It is baked into the client bundle at build time.


Development

Project structure

frame/
├── src/
│   ├── app/                    # Next.js App Router
│   │   ├── (app)/              # Authenticated routes
│   │   │   ├── dashboard/      # Deck listing
│   │   │   ├── deck/[id]/edit/ # Canvas editor
│   │   │   ├── deck/[id]/present/ # Presentation mode
│   │   │   └── workspace/      # Workspace settings
│   │   ├── (auth)/             # Login / register / reset
│   │   └── api/                # API routes
│   ├── components/
│   │   ├── canvas/             # Editor canvas, elements, toolbar, panels
│   │   └── sidebar/            # Slide sidebar + thumbnails
│   ├── hooks/                  # useYArray, useYMap (Yjs ↔ React bridge)
│   ├── lib/                    # Prisma client, auth, canvas helpers
│   └── store/                  # Zustand canvas store
├── server/
│   └── yjs-server.ts           # Standalone y-websocket server
└── prisma/
    └── schema.prisma           # Database schema

Available scripts

npm run dev        # Next.js dev server (Turbopack)
npm run ws         # Yjs WebSocket server
npm run build      # Production build
npm start          # Production server
npm test           # Vitest unit tests
npm run lint       # ESLint

Running tests

npm test
# or with coverage
npm test -- --coverage

Architecture notes

Yjs real-time sync

Each slide has its own Yjs document, keyed by slideId. The CanvasProvider component creates a WebsocketProvider that connects to the Yjs server. All canvas state (elements Y.Array of Y.Map) is CRDT-backed — no manual conflict resolution needed.

Browser ──WS──► y-websocket server (port 1234)
                     │
              persists Yjs updates
              in-memory (dev) / can
              be backed by a database

Prisma 7 driver adapters

Prisma 7 requires @prisma/adapter-pg — the default engine was removed. The setup in src/lib/db.ts uses PrismaPg with a connection string.

Export pipeline

Exports are async jobs:

  1. POST /api/decks/[id]/export → creates ExportJob record, triggers background processing
  2. Client polls GET /api/export-jobs/[jobId] every 2s
  3. On COMPLETED, user downloads via token-gated URL (no auth required for 1h)

Contributing

PRs welcome. Please open an issue first for significant changes.

  1. Fork the repo
  2. Create a branch: git checkout -b feat/my-feature
  3. Commit with conventional commits: feat:, fix:, docs:
  4. Open a PR

License

MIT

About

AI-powered collaborative presentation builder — real-time canvas editor, data connectors, Claude insights, PDF/PPTX export

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors