# Canvas-Website to FolkJS Migration Plan ## Overview This document outlines the transition from canvas-website (React + tldraw) to rspace-online (FolkJS web components). The goal is to simplify the architecture while preserving core functionality. ## Architecture Comparison | Aspect | canvas-website (tldraw) | rspace-online (FolkJS) | |--------|------------------------|------------------------| | **Framework** | React 18 + tldraw v3 | Web Components (Lit-style) | | **State** | tldraw store + Jotai atoms | Reactive properties + Automerge | | **Sync** | Cloudflare Durable Objects | WebSocket + Automerge CRDT | | **Shapes** | BaseBoxShapeUtil classes | FolkShape subclasses | | **Styling** | CSS-in-JS / CSS modules | CSS in template literals | | **Hooks** | React hooks (9 shared) | Class methods + utilities | ## Key Simplifications ### 1. No React - **Before**: JSX, useState, useEffect, useCallback, useMemo - **After**: Template literals, reactive properties, event listeners ### 2. No tldraw Abstraction Layer - **Before**: BaseBoxShapeUtil, editor.updateShape(), shape migrations - **After**: FolkShape base class, direct property updates, Automerge patches ### 3. Simpler State Management - **Before**: tldraw store → Automerge → tldraw store (bidirectional sync) - **After**: FolkShape → Automerge → FolkShape (direct sync via CommunitySync) ### 4. Web-Native APIs - **Before**: React context providers for auth, notifications, file system - **After**: Custom events, localStorage, native browser APIs ## Shape Porting Pattern ### tldraw Shape (Before) ```tsx export class MyShapeUtil extends BaseBoxShapeUtil { static type = 'my-shape' getDefaultProps(): MyShape['props'] { return { w: 300, h: 200, content: '' } } component(shape: MyShape) { const { content } = shape.props const handleChange = useCallback((e) => { this.editor.updateShape({ id: shape.id, props: { content: e.target.value } }) }, [shape.id]) return ( ` // Event listeners... return root } } ``` ## Migration Phases ### Phase 1: Foundation (4 shapes) **Status**: To Do - folk-slide (passive display) - folk-chat (real-time chat) - folk-google-item (data display) - folk-piano (interactive music) ### Phase 2: Core Data (4 shapes) **Status**: To Do - folk-embed (URL embeds) - folk-markdown (already done!) - folk-calendar (date picker + events) - folk-map (Mapbox/MapLibre collaborative maps) ### Phase 3: AI Integration (4 shapes) **Status**: To Do - folk-image-gen (fal.ai Flux) - folk-video-gen (WAN 2.1) - folk-prompt (LLM execution) - folk-transcription (Whisper) ### Phase 4: Advanced (5+ shapes) **Status**: To Do - folk-video-chat (Daily.co) - folk-obs-note (Obsidian sync) - folk-holon (H3 geo-indexing) - folk-workflow-block (visual workflows) - folk-zine-generator (AI zine creation) ## Shared Utilities to Port | React Hook | FolkJS Equivalent | Status | |------------|-------------------|--------| | useMaximize | maximizeShape() utility | To Do | | usePinnedToView | PinnedViewManager class | To Do | | useCalendarEvents | CalendarService class | To Do | | useWhisperTranscription | WhisperService class | To Do | | useLiveImage | LiveImageService class | To Do | ## Already Completed - [x] FolkShape base class with drag/resize/rotate - [x] FolkMarkdown (markdown editing) - [x] FolkWrapper (standardized header/actions) - [x] FolkArrow (shape connections) - [x] CommunitySync (Automerge integration) - [x] Server with WebSocket sync - [x] Subdomain routing for communities ## External Dependencies ### Keep (MCP or direct API) - fal.ai (image/video gen) - via MCP - Gemini (text gen) - via MCP - MapLibre GL (maps) - Daily.co (video chat) - Whisper API (transcription) ### Replace/Simplify - MDXEditor → simpler markdown renderer (already done) - tldraw → FolkJS (in progress) - React contexts → custom events + services ### Remove (tldraw-specific) - BaseBoxShapeUtil - Shape migrations - tldraw editor commands - tldraw store subscriptions ## Success Criteria 1. All 28 shapes ported to FolkJS web components 2. Real-time collaboration working via Automerge 3. Mobile touch support 4. Presence cursors showing other users 5. No React dependencies in runtime 6. Bundle size < 500KB (vs ~2MB current)