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):
Composables (React Hooks → Vue Composables):
Context Providers → Vue Provide/Inject:
Runtime & Store:
Integration Packages
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:
Shared Packages (Minimal Changes)
assistant-stream - Framework-agnostic streaming:
styles - CSS styles:
cloud - Assistant Cloud integration:
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
- Set up Vue 3 + TypeScript project structure
- Configure build tooling (Vite, tsup)
- Create base composables and context system
- Port core types and interfaces
Phase 2: Core Components
- Port Thread and ThreadList components
- Port Message and ContentPart components
- Port Composer and EditComposer
- Port ActionBar and BranchPicker
Phase 3: Runtime & State
- Port thread runtime with Vue reactivity
- Port message store with reactive updates
- Implement subscription system
- Add streaming support
Phase 4: Integrations
- Port vue-ai-sdk for Vercel AI SDK
- Port vue-langgraph for LangGraph
- Port vue-markdown and vue-syntax-highlighter
- Port vue-data-stream
Phase 5: Examples & Polish
- Create working examples
- Verify all features work
- Add documentation comments
- Final testing
Acceptance Criteria
Functional Requirements
Integration Requirements
Quality Requirements
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
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
Target Implementation
<script setup>syntaxPackages to Port
Core Package:
vue(Primary Focus)Port the main
reactpackage to Vue, translating:Primitives (Composable Components):
ActionBar- Action buttons for messagesAssistantModal- Modal container for assistantBranchPicker- Navigate between message branchesComposer- Message input compositionContentPart- Render different content typesEditComposer- Edit existing messagesMessage- Individual message displayThread- Thread container and managementThreadList- Multiple thread navigationComposables (React Hooks → Vue Composables):
useThread→useThread()useThreadRuntime→useThreadRuntime()useMessage→useMessage()useMessageRuntime→useMessageRuntime()useComposer→useComposer()useContentPart→useContentPart()useActionBar→useActionBar()useBranchPicker→useBranchPicker()Context Providers → Vue Provide/Inject:
AssistantRuntimeProvider→ Vue provide/inject patternThreadProvider→ Vue provide/inject patternMessageProvider→ Vue provide/inject patternComposerProvider→ Vue provide/inject patternRuntime & Store:
Integration Packages
vue-ai-sdk- AI SDK Integration:useVercelAIcomposablevue-langgraph- LangGraph Integration:useLangGraphcomposablevue-data-stream- Data Streaming:vue-markdown- Markdown Rendering:vue-syntax-highlighter- Code Highlighting:vue-form-kit- Form Integration:Shared Packages (Minimal Changes)
assistant-stream- Framework-agnostic streaming:styles- CSS styles:cloud- Assistant Cloud integration:Technical Translation Guide
React → Vue Pattern Mapping
useStateref()orreactive()useEffectonMounted,watch,watchEffectuseCallbackuseMemocomputed()useRefref()for values, template refs for DOMuseContextinject()createContextprovide()/inject()with InjectionKeyforwardRefdefineExpose()React.memochildrenprop<slot>/useSlots()render propsHOCComponent Structure
React Component:
Vue Equivalent:
Composable Pattern
React Hook:
Vue Composable:
Project Structure
Implementation Phases
Phase 1: Foundation
Phase 2: Core Components
Phase 3: Runtime & State
Phase 4: Integrations
Phase 5: Examples & Polish
Acceptance Criteria
Functional Requirements
Integration Requirements
Quality Requirements
.vueand.tsfiles compileDevelopment Notes
agent/directory as a scratchpad for planning and progress trackingagent/TODO.mdResources
packages/react/in source repo