TypeScript Blocks
Vibe runs on a TypeScript runtime, allowing you to drop into TypeScript whenever needed.
Basic TS Blocks
Section titled “Basic TS Blocks”let result = ts() { return Math.random() * 100;}Passing Variables
Section titled “Passing Variables”Pass Vibe variables into TypeScript:
let x = 10let y = 20
let sum = ts(x, y) { return x + y;}Variables are passed by name and available inside the block.
Named Bindings
Section titled “Named Bindings”Use name=expr to alias a variable or access a sub-expression:
let longVariableName = "hello"
let result = ts(s=longVariableName) { return s.toUpperCase();}Expression Bindings
Section titled “Expression Bindings”You can pass member access, array index, and slice expressions as parameters:
// Member accesslet obj: json = { name: "Alice", scores: [95, 87, 92] }let name = ts(n=obj.name) { return n.toUpperCase();}
// Array index accesslet items = [10, 20, 30, 40, 50]let first = ts(x=items[0]) { return x * 2; }let last = ts(x=items[-1]) { return x + 1; }
// Slice accesslet middle = ts(sub=items[1:4]) { return sub.reduce((a, b) => a + b, 0);}
// Chained accesslet score = ts(s=obj.scores[0]) { return s; }let tail = ts(rest=obj.scores[1:]) { return rest.length;}Supported expression patterns:
var.field— object member accessvar[n]— array index (supports negative indices)var[start:end]— array slice (start/end are optional)var.field[n].other— chained access
Types are automatically resolved through the access chain, enabling full type checking inside the ts block.
Type Checking
Section titled “Type Checking”Vibe performs compile-time type checking on ts() blocks. The types of Vibe variables are mapped to TypeScript types:
| Vibe Type | TypeScript Type |
|---|---|
text | string |
number | number |
boolean | boolean |
json | Record<string, unknown> |
let x: text = "hello"
// This will error at compile time - can't multiply a stringlet bad = ts(x) { return x * 2; // Error: left-hand side must be number}
// This is validlet good = ts(x) { return x.toUpperCase();}Return Type Inference
Section titled “Return Type Inference”Vibe automatically infers the return type of ts() blocks:
let num = ts() { return 42; } // Inferred as numberlet str = ts() { return "hello"; } // Inferred as textlet obj = ts() { return { a: 1 }; } // Inferred as json
// Type mismatch will errorlet x: text = ts() { return 42; } // Error: cannot assign number to textComplex Operations
Section titled “Complex Operations”JSON Processing
Section titled “JSON Processing”let jsonString = '{"name": "Alice", "age": 30}'
let parsed = ts(jsonString) { const data = JSON.parse(jsonString); return data.name.toUpperCase();}Array Operations
Section titled “Array Operations”let items = [1, 2, 3, 4, 5]
let doubled = ts(items) { return items.map(x => x * 2);}
let filtered = ts(items) { return items.filter(x => x > 2);}Async Operations
Section titled “Async Operations”let data = ts() { const response = await fetch('https://api.example.com/data'); return await response.json();}Dynamic Imports
Section titled “Dynamic Imports”Inside ts blocks, you can use dynamic await import() for Node built-ins:
let files = ts() { const { readdirSync } = await import('fs'); return readdirSync('.').filter(f => f.endsWith('.vibe'));}
let fullPath = ts(filename) { const { join } = await import('path'); return join(process.cwd(), filename);}Processing AI Results
Section titled “Processing AI Results”let aiResponse = do "Generate a list of 5 items as JSON"
let processed = ts(aiResponse) { const items = JSON.parse(aiResponse); return items .filter(item => item.score > 0.8) .map(item => item.name) .join(", ");}Return Types
Section titled “Return Types”TypeScript blocks can return any type:
// Return numberlet count: number = ts() { return 42; }
// Return textlet greeting: text = ts() { return "Hello"; }
// Return arraylet items: text[] = ts() { return ["a", "b", "c"]; }
// Return objectlet config: json = ts() { return { timeout: 5000, retries: 3 };}Error Handling
Section titled “Error Handling”let result = ts(input) { try { return JSON.parse(input); } catch (e) { return { error: e.message }; }}Using in Tools
Section titled “Using in Tools”TypeScript blocks are commonly used in tool implementations:
tool processData(data: json): json @description "Process and transform data"{ ts(data) { return { count: data.items.length, total: data.items.reduce((sum, item) => sum + item.value, 0), average: data.items.reduce((sum, item) => sum + item.value, 0) / data.items.length }; }}Best Practices
Section titled “Best Practices”Keep Blocks Focused
Section titled “Keep Blocks Focused”// Good - single purposelet parsed = ts(json) { return JSON.parse(json);}
// Avoid - too much logiclet result = ts(data) { // 50 lines of complex logic...}Use for What Vibe Can’t Do
Section titled “Use for What Vibe Can’t Do”// Good - Vibe doesn't have regexlet matches = ts(text) { return text.match(/\d+/g) || [];}
// Unnecessary - Vibe can do thislet sum = ts(a, b) { return a + b; }// Better: let sum = a + bHandle Errors Gracefully
Section titled “Handle Errors Gracefully”let safeResult = ts(input) { try { return { success: true, data: riskyOperation(input) }; } catch (e) { return { success: false, error: e.message }; }}