Skip to content
LogoLogo

Asset Imports

Turn project files into typed modules at compile time

VibeLang treats compiler-known files as tracked source inputs. Every non-code or foreign-source import uses standard import attributes; the type attribute selects a built-in or user-defined loader.

Built-In Formats

import config from "./config.json" with { type: "json" }
import literals from "./config.json" with {
  type: "json",
  mode: "const",
}
import systemPrompt from "./system.md" with { type: "text" }
import Prompt from "./coding-agent.mdx" with { type: "mdx" }

Attribute values are strings, matching JavaScript import-attribute syntax. JSON produces checked data, text produces a string, and MDX produces a typed component module. Parsed formats preserve source locations for diagnostics.

Const JSON

mode: "const" gives JSON a deeply readonly, literal-preserving type:

import config from "./config.json" with {
  type: "json",
  mode: "const",
}
 
// typeof config:
// {
//   readonly mode: "production"
//   readonly ports: readonly [80, 443]
// }

A normal { type: "json" } import retains the selected target's ordinary JSON-module widening behavior. There is no separate const-import grammar.

Markdown as Prompt Text

import systemPrompt from "./prompts/reviewer.md" with { type: "text" }
 
const response = (await model.generate({
  system: systemPrompt,
  prompt: reviewRequest,
})).unwrap()

There is no runtime file path to deploy. The compiler tracks and embeds the Markdown source.

Custom Loaders

// Proposed API shape
import { comptime } from "vibelang:comptime"
 
export default comptime.loader("yaml", (asset, context) => {
  const value = parseYaml(asset.text())
  const schema = context.import("./config.schema.json", {
    type: "json",
    mode: "const",
  })
  const config = validate(schema, value)
 
  return module {
    export default config
    export type Config = typeof config
  }
})

The registration and typed-module builder APIs remain proposed. Import attributes are the stable source-level selector.

Tracked Dependencies and Cache Identity

Loaders cannot read the ambient filesystem. Additional inputs enter through context.import(path, attributes). A loader result is keyed by source bytes, resolved loader implementation, all attributes, compiler/loader ABI versions, target, and transitive imported assets.

Raw Text and Bytes

import source from "./query.sql" with { type: "text" }
import image from "./logo.png" with { type: "bytes" }

Rust and Zig Source

import { tokenize } from "./parser.rs" with { type: "rust" }
import { hashMany } from "./hash.zig" with { type: "zig" }

The compiler invokes the foreign toolchain and produces checked bindings. Target, compiler versions, feature attributes, and the foreign dependency graph are tracked inputs.

Existing Native npm Packages

An imported npm package is code and uses an ordinary import:

import { transform } from "@acme/native-transform"

On Node or Bun, its Node-API addon remains a runtime dependency and contributes the corresponding TypeScript host requirement. VibeLang does not pretend such a package is portable to every target.

MDX Is General Purpose

The mdx loader yields a typed component module. Libraries may supply vocabularies for documentation, email, or prompts; those meanings are not built into the language.