Skip to content
LogoLogo

Features

A tour of the language model

VibeLang starts from TypeScript-shaped source and adds compiler semantics where they make application behavior explicit and statically analyzable.

:::warning Design documentation This page describes the intended language. The repository currently contains M0 scaffolding and runtime prototypes, not a complete .vibe compiler. :::

Values, Errors, and Requirements

async function getUser(
  id: string,
): Promise<Result<User, NotFound | DbError>> {
  const db = Db.context()
  const log = Logger.context()
  const row = (await db.findUser(id)).unwrap()
  if (row.isNone()) throw new NotFound(id)
  const user = User.from(row.unwrap())
  log.info(`loaded user:${id}`)
  return user
}

Result<User, NotFound | DbError> carries success and expected errors as an ordinary value. Db.context() and Logger.context() add requirements tracked by the compiler. Plain returns and Error throws are lifted inside Result-returning functions.

Result and Error APIs

const profile = loadProfile(id).match({
  ok: profile => profile,
  error: error => error.match({
    NotFound: () => Profile.guest(),
    InvalidProfile: error => { throw error },
  }),
})

Result supplies transformation, recovery, propagation, and must-use checking. Ordinary Error subclasses receive stable identity plus helpers such as is, matches, match, and rootCause. Learn more.

Optionals

const user = cache.get(id).match({
  some: user => user,
  none: () => guestUser,
})

Built-in Optional<T> keeps absence separate from Result errors and uses ordinary methods instead of new grammar. Learn more.

Capabilities and Layers

import { Context } from "vibelang/context"
 
abstract class Clock extends Context {
  abstract now(): Instant
}
 
function createToken(): Token {
  const clock = Clock.context()
  return Token.make({ issuedAt: clock.now() })
}

Layers construct and provide implementations. Requirements flow through callers until a Layer satisfies them. Learn more.

Expression-Oriented Control Flow

const tier = if (score >= 90) "gold"
  else if (score >= 60) "silver"
  else "bronze"

Blocks, conditionals, switches, and loops may produce values. Labeled breaks yield values; defer and errdefer keep cleanup adjacent to acquisition. Learn more.

Comptime

import { comptime } from "vibelang:comptime"
 
const schema = comptime(JSON.parse(embed("./routes.json")))
const Routes = comptime(deriveRoutes(schema))

comptime is an imported intrinsic, not a keyword. Evaluation is deterministic and dependency-tracked, and it may create types. Learn more.

Runtime Validation

type Signup = { email: string; age: number }
const SignupSchema = comptime(Schema.derive<Signup>())
const signup = SignupSchema.parse(input).unwrap()

Validation returns an ordinary Result. Learn more.

Typed Asset and Foreign Imports

import config from "./config.json" with { type: "json", mode: "const" }
import systemPrompt from "./prompts/system.md" with { type: "text" }
import { hash } from "./simd.zig" with { type: "zig" }

All non-code and foreign-source inputs use import attributes. Custom comptime loaders can turn SQL, GraphQL, YAML, or another format into typed modules. Learn more.

Multiple Targets

VibeLang targets TypeScript, native, and Wasm output. Platform operations are capabilities, and comptime.target selects implementations without emitting unused targets. Learn more.

Async and Concurrency

Async fallible work returns Promise<Result<A, E>>. Authored .vibe consumes Promises only with await; Promise instance chaining is banned.

const results = await Promise.all([
  loadProfile(id),
  loadActivity(id),
])
const [profile, activity] = Result.all(results).unwrap()

Learn more.

Durable Execution

import { durable } from "vibelang:flows"
 
const Build = durable(function Build(
  input: BuildInput,
): Result<Artifact, CompileError | PackageError> {
  const compiled = Compile.run({ source: input.source }).unwrap()
  return Package.run({ code: compiled.code })
})

The compiler lowers the checked body without invoking it. Plan mode reads emitted IR and runs neither the Flow nor any Action. Learn more.