Skip to content

Port assistant-ui from React to Vue.js: Complete Framework Translation #1

@jkbrooks

Description

@jkbrooks

Port assistant-ui from React to Vue.js

Overview

Translate the assistant-ui library from React to Vue.js, creating a complete Vue.js equivalent that maintains full feature parity with the React implementation. This includes all core components, composables (Vue equivalent of hooks), integrations, and styling.

Source Material

  • Source Repository: assistant-ui/assistant-ui (React/TypeScript)
  • Framework: React with TypeScript
  • Key Patterns: Radix-style composable primitives, custom hooks, context providers

Target Implementation

  • Framework: Vue.js 3 with TypeScript
  • Composition API: Use <script setup> syntax
  • State Management: Vue composables (equivalent to React hooks)
  • Reactivity: Vue reactive/ref system

Packages to Port

Core Package: vue (Primary Focus)

Port the main react package to Vue, translating:

Primitives (Composable Components):

  • ActionBar - Action buttons for messages
  • AssistantModal - Modal container for assistant
  • BranchPicker - Navigate between message branches
  • Composer - Message input composition
  • ContentPart - Render different content types
  • EditComposer - Edit existing messages
  • Message - Individual message display
  • Thread - Thread container and management
  • ThreadList - Multiple thread navigation

Composables (React Hooks → Vue Composables):

  • useThreaduseThread()
  • useThreadRuntimeuseThreadRuntime()
  • useMessageuseMessage()
  • useMessageRuntimeuseMessageRuntime()
  • useComposeruseComposer()
  • useContentPartuseContentPart()
  • useActionBaruseActionBar()
  • useBranchPickeruseBranchPicker()

Context Providers → Vue Provide/Inject:

  • AssistantRuntimeProvider → Vue provide/inject pattern
  • ThreadProvider → Vue provide/inject pattern
  • MessageProvider → Vue provide/inject pattern
  • ComposerProvider → Vue provide/inject pattern

Runtime & Store:

  • Thread runtime state management
  • Message store with reactive updates
  • Subscription system for real-time updates

Integration Packages

vue-ai-sdk - AI SDK Integration:

  • useVercelAI composable
  • Streaming response handling
  • Provider configuration

vue-langgraph - LangGraph Integration:

  • useLangGraph composable
  • LangGraph Cloud support
  • Agent workflow integration

vue-data-stream - Data Streaming:

  • Stream parsing utilities
  • SSE handling for Vue

vue-markdown - Markdown Rendering:

  • Markdown component for Vue
  • Code syntax highlighting integration
  • Custom renderer support

vue-syntax-highlighter - Code Highlighting:

  • Syntax highlighter component
  • Theme support
  • Language detection

vue-form-kit - Form Integration:

  • FormKit adapter for composer
  • Validation integration

Shared Packages (Minimal Changes)

assistant-stream - Framework-agnostic streaming:

  • Verify compatibility with Vue
  • Add Vue-specific utilities if needed

styles - CSS styles:

  • Ensure CSS works with Vue components
  • Add Vue-specific class bindings

cloud - Assistant Cloud integration:

  • Verify API compatibility
  • Add Vue-specific client wrapper

Technical Translation Guide

React → Vue Pattern Mapping

React Pattern Vue.js Equivalent
useState ref() or reactive()
useEffect onMounted, watch, watchEffect
useCallback Regular function (auto-tracked)
useMemo computed()
useRef ref() for values, template refs for DOM
useContext inject()
createContext provide() / inject() with InjectionKey
forwardRef defineExpose()
React.memo Not needed (Vue auto-optimizes)
children prop <slot> / useSlots()
render props Scoped slots
HOC Composables or renderless components

Component Structure

React Component:

export function MessageContent({ message }: Props) {
  const { isEditing } = useMessage();
  return <div>{isEditing ? <Editor /> : <Display />}</div>;
}

Vue Equivalent:

<script setup lang="ts">
interface Props {
  message: Message;
}
defineProps<Props>();
const { isEditing } = useMessage();
</script>

<template>
  <div>
    <Editor v-if="isEditing" />
    <Display v-else />
  </div>
</template>

Composable Pattern

React Hook:

export function useThread() {
  const context = useContext(ThreadContext);
  const [messages, setMessages] = useState([]);
  useEffect(() => { /* subscribe */ }, []);
  return { messages, send };
}

Vue Composable:

export function useThread() {
  const context = inject(ThreadKey);
  const messages = ref<Message[]>([]);
  onMounted(() => { /* subscribe */ });
  return { messages, send };
}

Project Structure

packages/
├── vue/                          # Core Vue components
│   ├── src/
│   │   ├── components/
│   │   │   ├── ActionBar/
│   │   │   ├── AssistantModal/
│   │   │   ├── BranchPicker/
│   │   │   ├── Composer/
│   │   │   ├── ContentPart/
│   │   │   ├── EditComposer/
│   │   │   ├── Message/
│   │   │   ├── Thread/
│   │   │   └── ThreadList/
│   │   ├── composables/
│   │   │   ├── useThread.ts
│   │   │   ├── useMessage.ts
│   │   │   ├── useComposer.ts
│   │   │   └── ...
│   │   ├── context/
│   │   │   ├── AssistantContext.ts
│   │   │   ├── ThreadContext.ts
│   │   │   └── ...
│   │   ├── runtime/
│   │   │   └── ...
│   │   └── index.ts
│   ├── package.json
│   └── tsconfig.json
├── vue-ai-sdk/                   # AI SDK integration
├── vue-langgraph/                # LangGraph integration
├── vue-data-stream/              # Data streaming
├── vue-markdown/                 # Markdown rendering
├── vue-syntax-highlighter/       # Code highlighting
├── vue-form-kit/                 # Form integration
├── assistant-stream/             # Shared streaming (minimal changes)
├── styles/                       # Shared styles
└── cloud/                        # Cloud integration
examples/
├── basic-example/                # Basic Vue example
├── with-ai-sdk-v5/               # AI SDK integration example
├── with-langgraph/               # LangGraph example
└── with-cloud/                   # Cloud integration example

Implementation Phases

Phase 1: Foundation

  1. Set up Vue 3 + TypeScript project structure
  2. Configure build tooling (Vite, tsup)
  3. Create base composables and context system
  4. Port core types and interfaces

Phase 2: Core Components

  1. Port Thread and ThreadList components
  2. Port Message and ContentPart components
  3. Port Composer and EditComposer
  4. Port ActionBar and BranchPicker

Phase 3: Runtime & State

  1. Port thread runtime with Vue reactivity
  2. Port message store with reactive updates
  3. Implement subscription system
  4. Add streaming support

Phase 4: Integrations

  1. Port vue-ai-sdk for Vercel AI SDK
  2. Port vue-langgraph for LangGraph
  3. Port vue-markdown and vue-syntax-highlighter
  4. Port vue-data-stream

Phase 5: Examples & Polish

  1. Create working examples
  2. Verify all features work
  3. Add documentation comments
  4. Final testing

Acceptance Criteria

Functional Requirements

  • All core components render correctly
  • Composables provide reactive state
  • Context/provide-inject works for nested components
  • Streaming messages display in real-time
  • Message editing works
  • Branch navigation works
  • Thread switching works

Integration Requirements

  • AI SDK integration works for chat
  • LangGraph integration works
  • Markdown renders correctly
  • Code syntax highlighting works
  • Cloud integration connects

Quality Requirements

  • TypeScript types are correct
  • All .vue and .ts files compile
  • At least one working example per integration
  • Follows Vue 3 best practices

Development Notes

  • Use the agent/ directory as a scratchpad for planning and progress tracking
  • Commit frequently after completing each component or composable
  • Keep track of progress in agent/TODO.md
  • When translating React patterns, prioritize Vue idioms over direct ports
  • Test components work together, not just in isolation

Resources

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions