# Framework Integration Guide
Brainy 3.0 is **framework-first** - designed from the ground up to work seamlessly with modern JavaScript frameworks. This guide shows you how to integrate Brainy into any framework.
## 🎯 Why Framework-First?
Traditional AI databases require complex browser polyfills and bundler configurations. Brainy 3.0 trusts your framework to handle this:
- **Zero configuration**: Just `import { Brainy } from '@soulcraft/brainy'`
- **Framework responsibility**: Let Next.js, Vite, Webpack handle Node.js polyfills
- **Cleaner code**: No browser-specific entry points or conditional imports
- **Better DX**: Same API everywhere - browser, server, edge
## 🚀 Quick Start
### Install Brainy
```bash
npm install @soulcraft/brainy
```
### Basic Integration
```javascript
import { Brainy } from '@soulcraft/brainy'
// Works in any framework!
const brain = new Brainy()
await brain.init()
// Add data
await brain.add({
data: "Framework integration is awesome!",
type: "concept",
metadata: { framework: "any" }
})
// Search
const results = await brain.find("framework integration")
```
## ⚛️ React Integration
### Basic Hook Pattern
```jsx
import { useState, useEffect, useCallback } from 'react'
import { Brainy } from '@soulcraft/brainy'
function useBrainy() {
const [brain, setBrain] = useState(null)
const [isReady, setIsReady] = useState(false)
useEffect(() => {
const initBrain = async () => {
const newBrain = new Brainy({
storage: { type: 'opfs' } // Browser storage
})
await newBrain.init()
setBrain(newBrain)
setIsReady(true)
}
initBrain()
}, [])
return { brain, isReady }
}
// Usage in component
function SearchComponent() {
const { brain, isReady } = useBrainy()
const [results, setResults] = useState([])
const handleSearch = useCallback(async (query) => {
if (!isReady) return
const searchResults = await brain.find(query)
setResults(searchResults)
}, [brain, isReady])
if (!isReady) return
Loading AI...
return (
handleSearch(e.target.value)}
/>
{results.map(result => (
{result.data}
Score: {(result.score * 100).toFixed(1)}%
))}
)
}
```
### React Context Pattern
```jsx
import React, { createContext, useContext, useEffect, useState } from 'react'
import { Brainy } from '@soulcraft/brainy'
const BrainyContext = createContext()
export function BrainyProvider({ children }) {
const [brain, setBrain] = useState(null)
const [isReady, setIsReady] = useState(false)
useEffect(() => {
const initBrain = async () => {
const newBrain = new Brainy()
await newBrain.init()
setBrain(newBrain)
setIsReady(true)
}
initBrain()
}, [])
return (
{children}
)
}
export function useBrainContext() {
const context = useContext(BrainyContext)
if (!context) {
throw new Error('useBrainContext must be used within BrainyProvider')
}
return context
}
```
## 🟢 Vue.js Integration
### Composition API
```vue
```
### Vue 3 Plugin
```javascript
// plugins/brainy.js
import { Brainy } from '@soulcraft/brainy'
export default {
install(app, options) {
const brain = new Brainy(options)
app.config.globalProperties.$brain = brain
app.provide('brain', brain)
// Initialize on app mount
brain.init()
}
}
// main.js
import { createApp } from 'vue'
import BrainyPlugin from './plugins/brainy'
const app = createApp(App)
app.use(BrainyPlugin, {
storage: { type: 'opfs' }
})
```
## 🅰️ Angular Integration
### Service Pattern
```typescript
// brainy.service.ts
import { Injectable } from '@angular/core'
import { BehaviorSubject, Observable } from 'rxjs'
import { Brainy } from '@soulcraft/brainy'
@Injectable({
providedIn: 'root'
})
export class BrainyService {
private brain: Brainy
private readySubject = new BehaviorSubject(false)
ready$: Observable = this.readySubject.asObservable()
constructor() {
this.initBrain()
}
private async initBrain() {
this.brain = new Brainy({
storage: { type: 'opfs' }
})
await this.brain.init()
this.readySubject.next(true)
}
async search(query: string): Promise {
if (!this.readySubject.value) {
throw new Error('Brain not ready')
}
return await this.brain.find(query)
}
async add(data: any, type: string, metadata?: any): Promise {
if (!this.readySubject.value) {
throw new Error('Brain not ready')
}
return await this.brain.add({ data, type, metadata })
}
}
```
```typescript
// search.component.ts
import { Component } from '@angular/core'
import { BrainyService } from './brainy.service'
@Component({
selector: 'app-search',
template: `
`
})
export class SearchComponent {
query = ''
results: any[] = []
constructor(private brainyService: BrainyService) {}
async search() {
if (!this.query) return
this.results = await this.brainyService.search(this.query)
}
}
```
## 🚀 Next.js Integration
### App Router (Next.js 13+)
```jsx
// app/providers.jsx
'use client'
import { createContext, useContext, useEffect, useState } from 'react'
import { Brainy } from '@soulcraft/brainy'
const BrainyContext = createContext()
export function BrainyProvider({ children }) {
const [brain, setBrain] = useState(null)
const [isReady, setIsReady] = useState(false)
useEffect(() => {
const initBrain = async () => {
const newBrain = new Brainy()
await newBrain.init()
setBrain(newBrain)
setIsReady(true)
}
initBrain()
}, [])
return (
{children}
)
}
export const useBrainy = () => useContext(BrainyContext)
```
```jsx
// app/layout.jsx
import { BrainyProvider } from './providers'
export default function RootLayout({ children }) {
return (
{children}
)
}
```
### API Routes
```javascript
// app/api/search/route.js
import { Brainy } from '@soulcraft/brainy'
const brain = new Brainy({
storage: { type: 'filesystem', path: './data' }
})
await brain.init()
export async function POST(request) {
const { query } = await request.json()
const results = await brain.find(query)
return Response.json({ results })
}
```
## 🔷 Svelte Integration
```svelte
{#each results as result}
{result.data}
Score: {(result.score * 100).toFixed(1)}%
{/each}
```
## 🌟 Solid.js Integration
```jsx
import { createSignal, onMount } from 'solid-js'
import { Brainy } from '@soulcraft/brainy'
function SearchComponent() {
const [brain, setBrain] = createSignal(null)
const [isReady, setIsReady] = createSignal(false)
const [query, setQuery] = createSignal('')
const [results, setResults] = createSignal([])
onMount(async () => {
const newBrain = new Brainy()
await newBrain.init()
setBrain(newBrain)
setIsReady(true)
})
const search = async () => {
if (!isReady() || !query()) return
const searchResults = await brain().find(query())
setResults(searchResults)
}
return (
)
}
```
## 📦 Bundler Configuration
### Vite (Recommended)
```javascript
// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
define: {
global: 'globalThis'
},
optimizeDeps: {
include: ['@soulcraft/brainy']
}
})
```
### Webpack
```javascript
// webpack.config.js
module.exports = {
resolve: {
fallback: {
"fs": false,
"path": require.resolve("path-browserify"),
"crypto": require.resolve("crypto-browserify")
}
},
plugins: [
new webpack.ProvidePlugin({
global: 'global'
})
]
}
```
### Rollup
```javascript
// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
export default {
plugins: [
nodeResolve({
browser: true,
preferBuiltins: false
}),
commonjs()
]
}
```
## 🌐 SSR/SSG Considerations
### Server-Side Rendering
```javascript
// Check if running in browser
if (typeof window !== 'undefined') {
// Browser-only code
const brain = new Brainy({
storage: { type: 'opfs' }
})
}
// Or use dynamic imports
const initBrainForBrowser = async () => {
if (typeof window === 'undefined') return null
const { Brainy } = await import('@soulcraft/brainy')
const brain = new Brainy()
await brain.init()
return brain
}
```
### Static Site Generation
```javascript
// For build-time usage
import { Brainy } from '@soulcraft/brainy'
export async function generateStaticProps() {
const brain = new Brainy({
storage: { type: 'filesystem', path: './content' }
})
await brain.init()
// Build a search index — export the whole brain as a portable BackupData document
const backup = await brain.data().then(d => d.export())
return {
props: { searchIndex: backup.entities }
}
}
```
## 🔧 Framework-Specific Tips
### React
- Use `useCallback` for search functions to prevent re-renders
- Consider `useMemo` for expensive brain operations
- Implement cleanup in `useEffect` for proper memory management
### Vue
- Use `shallowRef` for the brain instance (it's not reactive data)
- Consider Pinia for global brain state management
- Use `watchEffect` for reactive search queries
### Angular
- Implement proper dependency injection with services
- Use RxJS observables for reactive search
- Consider lazy loading brain in feature modules
### Next.js
- Use dynamic imports for client-side only features
- Consider API routes for server-side brain operations
- Implement proper error boundaries
## 🚨 Common Issues & Solutions
### Issue: "crypto is not defined"
**Solution**: Your framework should handle this automatically. If not:
```javascript
// Add to your bundle config
define: {
global: 'globalThis'
}
```
### Issue: "fs module not found"
**Solution**: This is expected in browsers. Use browser-compatible storage:
```javascript
const brain = new Brainy({
storage: { type: 'opfs' } // Or 'memory' for development
})
```
### Issue: Large bundle size
**Solution**: Use dynamic imports for optional features:
```javascript
const brain = await import('@soulcraft/brainy').then(m => new m.Brainy())
```
### Issue: SSR hydration mismatch
**Solution**: Initialize brain only on client:
```javascript
useEffect(() => {
// Browser-only initialization
initBrain()
}, [])
```
## 🎯 Best Practices
1. **Initialize Once**: Create brain instance at app level, not component level
2. **Use Context**: Share brain instance across components with context/providers
3. **Handle Loading**: Always show loading states during brain initialization
4. **Error Boundaries**: Implement proper error handling for brain operations
5. **Memory Management**: Clean up brain instances on unmount
6. **Storage Strategy**: Choose appropriate storage for your deployment target
## 📚 Next Steps
- [Next.js Integration Guide](nextjs-integration.md) - Detailed Next.js examples
- [Vue.js Integration Guide](vue-integration.md) - Complete Vue.js patterns
- [API Reference](../api/README.md) - Complete API documentation
- [Production Deployment](../deployment/CLOUD_DEPLOYMENT_GUIDE.md) - Deploy to production
## 🤝 Community Examples
Check out community examples in the [examples repository](https://github.com/soulcraftlabs/brainy-examples):
- React + TypeScript starter
- Vue 3 + Composition API
- Next.js full-stack app
- Svelte SPA with search
- Angular enterprise app