Documentation Index
Fetch the complete documentation index at: https://docs.morphllm.com/llms.txt
Use this file to discover all available pages before exploring further.
Vibe Compiler
The Vibe Compiler validates generated code before execution, blocking dangerous patterns and enforcing security constraints. It’s used internally by VibeFrame but can also be used directly for pre-validation.
Usage
import { VibeCompiler } from 'genkit'
const compiler = new VibeCompiler()
try {
const compiled = await compiler.compile(generatedCode)
console.log('Code is valid:', compiled.hash)
} catch (error) {
console.error('Validation failed:', error.message)
}
Configuration
const compiler = new VibeCompiler({
// Allowed import sources (default: ['react'])
allowedImports: ['react', 'recharts', 'date-fns'],
// Maximum code size in bytes (default: 100KB)
maxCodeSize: 200_000,
// Enable caching of compiled results (default: true)
cache: true
})
Security Checks
Blocked Patterns
The compiler rejects code containing:
// Dynamic code execution
eval('...') // ❌ Blocked
Function('...') // ❌ Blocked
new Function('...') // ❌ Blocked
// Dynamic imports
import('...') // ❌ Blocked
require('...') // ❌ Blocked
// Global access
process.env // ❌ Blocked
global.anything // ❌ Blocked
window.anything // ❌ Blocked
document.anything // ❌ Blocked
// Prototype pollution
obj.__proto__ // ❌ Blocked
obj.constructor[...] // ❌ Blocked
Import Validation
Only whitelisted imports are allowed:
// With default config (allowedImports: ['react'])
import React from 'react' // ✅ Allowed
import { useState } from 'react' // ✅ Allowed
import Chart from 'recharts' // ❌ Blocked
// With custom config
const compiler = new VibeCompiler({
allowedImports: ['react', 'recharts']
})
import { BarChart } from 'recharts' // ✅ Now allowed
Size Limits
const compiler = new VibeCompiler({
maxCodeSize: 50_000 // 50KB limit
})
// Large code will be rejected
await compiler.compile(hugeCodeString)
// Error: Code size (150000 bytes) exceeds maximum (50000 bytes)
Compiled Output
interface CompiledComponent {
// Original source code
code: string
// Hash for caching
hash: string
// Render function (in full implementation)
render(data?: Record<string, unknown>): ReactNode
}
Pre-validation Pattern
Validate before saving to database:
import { VibeCompiler, createVibeApi } from 'genkit'
const compiler = new VibeCompiler()
const vibe = createVibeApi({ storage })
async function saveComponent(input: { userId: string; name: string; code: string }) {
// Validate first
try {
await compiler.compile(input.code)
} catch (error) {
throw new Error(`Invalid code: ${error.message}`)
}
// Save if valid
return vibe.save(input)
}
API Integration
// app/api/vibe/validate/route.ts
import { VibeCompiler } from 'genkit'
const compiler = new VibeCompiler({
allowedImports: ['react', 'recharts', 'lucide-react']
})
export async function POST(request: Request) {
const { code } = await request.json()
try {
const compiled = await compiler.compile(code)
return Response.json({
valid: true,
hash: compiled.hash
})
} catch (error) {
return Response.json({
valid: false,
error: error.message
}, { status: 400 })
}
}
Caching
Compiled results are cached by code hash:
const compiler = new VibeCompiler({ cache: true })
// First compile - validates code
await compiler.compile(code) // ~10ms
// Second compile - returns cached result
await compiler.compile(code) // ~0.1ms
// Clear cache if needed
compiler.clearCache()
Custom Validation
Extend the compiler for additional checks:
class CustomCompiler extends VibeCompiler {
async compile(code: string) {
// Run base validation
const result = await super.compile(code)
// Add custom checks
if (code.includes('alert(')) {
throw new Error('alert() is not allowed')
}
if (code.length < 50) {
throw new Error('Code is too short to be valid')
}
return result
}
}
Error Messages
The compiler provides detailed error messages:
try {
await compiler.compile(code)
} catch (error) {
// Possible error messages:
// "Code size (150000 bytes) exceeds maximum allowed (100000 bytes)"
// "Code contains potentially dangerous pattern: eval\\s*\\("
// "Import not allowed: axios"
}
Best Practices
1. Validate on Both Client and Server
// Client-side (quick feedback)
const clientCompiler = new VibeCompiler()
try {
await clientCompiler.compile(code)
setError(null)
} catch (e) {
setError(e.message)
return
}
// Server-side (authoritative)
const response = await fetch('/api/vibe/validate', {
method: 'POST',
body: JSON.stringify({ code })
})
// Dashboard app - allow charting libraries
const dashboardCompiler = new VibeCompiler({
allowedImports: ['react', 'recharts', 'd3', 'date-fns']
})
// Form builder - allow form libraries
const formCompiler = new VibeCompiler({
allowedImports: ['react', 'react-hook-form', 'zod']
})
3. Set Reasonable Size Limits
// Widgets should be small
const widgetCompiler = new VibeCompiler({
maxCodeSize: 20_000 // 20KB
})
// Full pages can be larger
const pageCompiler = new VibeCompiler({
maxCodeSize: 100_000 // 100KB
})