diff --git a/docs/runtime/yaml.mdx b/docs/runtime/yaml.mdx index cf45e28d6c..7e3b67801b 100644 --- a/docs/runtime/yaml.mdx +++ b/docs/runtime/yaml.mdx @@ -1,605 +1,607 @@ ---- -title: YAML -description: Use Bun's built-in support for YAML files through both runtime APIs and bundler integration ---- - -In Bun, YAML is a first-class citizen alongside JSON and TOML. You can: - -- Parse YAML strings with `Bun.YAML.parse` and stringify objects with `Bun.YAML.stringify` -- `import` & `require` YAML files as modules at runtime (including hot reloading & watch mode support) -- `import` & `require` YAML files in frontend apps via bun's bundler - ---- - -## Conformance - -Bun's YAML parser currently passes over 90% of the official YAML test suite. While we're actively working on reaching 100% conformance, the current implementation covers the vast majority of real-world use cases. The parser is written in Zig for optimal performance and is continuously being improved. - ---- - -## Runtime API - -### `Bun.YAML.parse()` - -Parse a YAML string into a JavaScript object. - -```ts -import { YAML } from "bun"; -const text = ` -name: John Doe -age: 30 -email: john@example.com -hobbies: - - reading - - coding - - hiking -`; - -const data = YAML.parse(text); -console.log(data); -// { -// name: "John Doe", -// age: 30, -// email: "john@example.com", -// hobbies: ["reading", "coding", "hiking"] -// } -``` - -#### Multi-document YAML - -When parsing YAML with multiple documents (separated by `---`), `Bun.YAML.parse()` returns an array: - -```ts -const multiDoc = ` ---- -name: Document 1 ---- -name: Document 2 ---- -name: Document 3 -`; - -const docs = Bun.YAML.parse(multiDoc); -console.log(docs); -// [ -// { name: "Document 1" }, -// { name: "Document 2" }, -// { name: "Document 3" } -// ] -``` - -#### Supported YAML Features - -Bun's YAML parser supports the full YAML 1.2 specification, including: - -- **Scalars**: strings, numbers, booleans, null values -- **Collections**: sequences (arrays) and mappings (objects) -- **Anchors and Aliases**: reusable nodes with `&` and `*` -- **Tags**: type hints like `!!str`, `!!int`, `!!float`, `!!bool`, `!!null` -- **Multi-line strings**: literal (`|`) and folded (`>`) scalars -- **Comments**: using `#` -- **Directives**: `%YAML` and `%TAG` - -```ts -const yaml = ` -# Employee record -employee: &emp - name: Jane Smith - department: Engineering - skills: - - JavaScript - - TypeScript - - React - -manager: *emp # Reference to employee - -config: !!str 123 # Explicit string type - -description: | - This is a multi-line - literal string that preserves - line breaks and spacing. - -summary: > - This is a folded string - that joins lines with spaces - unless there are blank lines. -`; - -const data = Bun.YAML.parse(yaml); -``` - -#### Error Handling - -`Bun.YAML.parse()` throws a `SyntaxError` if the YAML is invalid: - -```ts -try { - Bun.YAML.parse("invalid: yaml: content:"); -} catch (error) { - console.error("Failed to parse YAML:", error.message); -} -``` - -### `Bun.YAML.stringify()` - -Convert a JavaScript object into a YAML string. - -```ts -import { YAML } from "bun"; - -const obj = { - name: "John Doe", - age: 30, - email: "john@example.com", - hobbies: ["reading", "coding", "hiking"], -}; - -const yaml = Bun.YAML.stringify(obj, null, 2); -console.log(yaml); -// name: John Doe -// age: 30 -// email: john@example.com -// hobbies: -// - reading -// - coding -// - hiking -``` - -The signature is similar to `JSON.stringify()`: - -```ts -Bun.YAML.stringify(value, replacer?, space?) -``` - -The `space` parameter controls indentation (default: 2). With `space: 0`, YAML outputs in compact flow style on a single line: - -```ts -const compact = Bun.YAML.stringify(obj, null, 0); -// {name: John Doe,age: 30,email: john@example.com,hobbies: [reading,coding,hiking]} -``` - ---- - -## Module Import - -### ES Modules - -You can import YAML files directly as ES modules. The YAML content is parsed and made available as both default and named exports: - -```yaml config.yaml -database: - host: localhost - port: 5432 - name: myapp - -redis: - host: localhost - port: 6379 - -features: - auth: true - rateLimit: true - analytics: false -``` - -#### Default Import - -```ts app.ts icon="/icons/typescript.svg" -import config from "./config.yaml"; - -console.log(config.database.host); // "localhost" -console.log(config.redis.port); // 6379 -``` - -#### Named Imports - -You can destructure top-level YAML properties as named imports: - -```ts app.ts icon="/icons/typescript.svg" -import { database, redis, features } from "./config.yaml"; - -console.log(database.host); // "localhost" -console.log(redis.port); // 6379 -console.log(features.auth); // true -``` - -Or combine both: - -```ts app.ts icon="/icons/typescript.svg" -import config, { database, features } from "./config.yaml"; - -// Use the full config object -console.log(config); - -// Or use specific parts -if (features.rateLimit) { - setupRateLimiting(database); -} -``` - -### CommonJS - -YAML files can also be required in CommonJS: - -```ts app.ts icon="/icons/typescript.svg" -const config = require("./config.yaml"); -console.log(config.database.name); // "myapp" - -// Destructuring also works -const { database, redis } = require("./config.yaml"); -console.log(database.port); // 5432 -``` - -### TypeScript - -Unlike JSON files, TypeScript doesn't automatically type YAML imports. Add type definitions by creating a `.d.ts` file with the same name as your YAML file: - -```ts config.yaml.d.ts icon="/icons/typescript.svg" -const contents: { - database: { - host: string; - port: number; - name: string; - }; - server: { - port: number; - timeout: number; - }; - features: { - auth: boolean; - rateLimit: boolean; - }; -}; - -export = contents; -``` - ---- - -## Hot Reloading with YAML - -One of the most powerful features of Bun's YAML support is hot reloading. When you run your application with `bun --hot`, changes to YAML files are automatically detected and reloaded without closing connections - -### Configuration Hot Reloading - -```yaml config.yaml -server: - port: 3000 - host: localhost - -features: - debug: true - verbose: false -``` - -```ts server.ts icon="/icons/typescript.svg" -import { server, features } from "./config.yaml"; - -console.log(`Starting server on ${server.host}:${server.port}`); - -if (features.debug) { - console.log("Debug mode enabled"); -} - -// Your server code here -Bun.serve({ - port: server.port, - hostname: server.host, - fetch(req) { - if (features.verbose) { - console.log(`${req.method} ${req.url}`); - } - return new Response("Hello World"); - }, -}); -``` - -Run with hot reloading: - -```bash terminal icon="terminal" -bun --hot server.ts -``` - -Now when you modify `config.yaml`, the changes are immediately reflected in your running application. This is perfect for: - -- Adjusting configuration during development -- Testing different settings without restarts -- Live debugging with configuration changes -- Feature flag toggling - ---- - -## Configuration Management - -### Environment-Based Configuration - -YAML excels at managing configuration across different environments: - -```yaml config.yaml -defaults: &defaults - timeout: 5000 - retries: 3 - cache: - enabled: true - ttl: 3600 - -development: - <<: *defaults - api: - url: http://localhost:4000 - key: dev_key_12345 - logging: - level: debug - pretty: true - -staging: - <<: *defaults - api: - url: https://staging-api.example.com - key: ${STAGING_API_KEY} - logging: - level: info - pretty: false - -production: - <<: *defaults - api: - url: https://api.example.com - key: ${PROD_API_KEY} - cache: - enabled: true - ttl: 86400 - logging: - level: error - pretty: false -``` - -```ts app.ts icon="/icons/typescript.svg" -import configs from "./config.yaml"; - -const env = process.env.NODE_ENV || "development"; -const config = configs[env]; - -// Environment variables in YAML values can be interpolated -function interpolateEnvVars(obj: any): any { - if (typeof obj === "string") { - return obj.replace(/\${(\w+)}/g, (_, key) => process.env[key] || ""); - } - if (typeof obj === "object") { - for (const key in obj) { - obj[key] = interpolateEnvVars(obj[key]); - } - } - return obj; -} - -export default interpolateEnvVars(config); -``` - -### Feature Flags Configuration - -```yaml features.yaml -features: - newDashboard: - enabled: true - rolloutPercentage: 50 - allowedUsers: - - admin@example.com - - beta@example.com - - experimentalAPI: - enabled: false - endpoints: - - /api/v2/experimental - - /api/v2/beta - - darkMode: - enabled: true - default: auto # auto, light, dark -``` - -```ts feature-flags.ts icon="/icons/typescript.svg" -import { features } from "./features.yaml"; - -export function isFeatureEnabled(featureName: string, userEmail?: string): boolean { - const feature = features[featureName]; - - if (!feature?.enabled) { - return false; - } - - // Check rollout percentage - if (feature.rolloutPercentage < 100) { - const hash = hashCode(userEmail || "anonymous"); - if (hash % 100 >= feature.rolloutPercentage) { - return false; - } - } - - // Check allowed users - if (feature.allowedUsers && userEmail) { - return feature.allowedUsers.includes(userEmail); - } - - return true; -} - -// Use with hot reloading to toggle features in real-time -if (isFeatureEnabled("newDashboard", user.email)) { - renderNewDashboard(); -} else { - renderLegacyDashboard(); -} -``` - -### Database Configuration - -```yaml database.yaml icon="yaml" -connections: - primary: - type: postgres - host: ${DB_HOST:-localhost} - port: ${DB_PORT:-5432} - database: ${DB_NAME:-myapp} - username: ${DB_USER:-postgres} - password: ${DB_PASS} - pool: - min: 2 - max: 10 - idleTimeout: 30000 - - cache: - type: redis - host: ${REDIS_HOST:-localhost} - port: ${REDIS_PORT:-6379} - password: ${REDIS_PASS} - db: 0 - - analytics: - type: clickhouse - host: ${ANALYTICS_HOST:-localhost} - port: 8123 - database: analytics - -migrations: - autoRun: ${AUTO_MIGRATE:-false} - directory: ./migrations - -seeds: - enabled: ${SEED_DB:-false} - directory: ./seeds -``` - -```ts db.ts icon="/icons/typescript.svg" -import { connections, migrations } from "./database.yaml"; -import { createConnection } from "./database-driver"; - -// Parse environment variables with defaults -function parseConfig(config: any) { - return JSON.parse( - JSON.stringify(config).replace( - /\${([^:-]+)(?::([^}]+))?}/g, - (_, key, defaultValue) => process.env[key] || defaultValue || "", - ), - ); -} - -const dbConfig = parseConfig(connections); - -export const db = await createConnection(dbConfig.primary); -export const cache = await createConnection(dbConfig.cache); -export const analytics = await createConnection(dbConfig.analytics); - -// Auto-run migrations if configured -if (parseConfig(migrations).autoRun === "true") { - await runMigrations(db, migrations.directory); -} -``` - -### Generating YAML Files - -You can use `Bun.YAML.stringify()` to programmatically create YAML configuration files. It handles complex data structures including nested objects, arrays, and objects within arrays. When you reference the same object multiple times, YAML automatically creates anchors (`&`) and aliases (`*`) to avoid duplication: - - -```ts generate-config.ts icon="/icons/typescript.svg" -import { YAML } from "bun"; - -const defaults = { - timeout: 30000, - retries: 3, -}; - -const config = { - defaults, - development: { - defaults, - host: "localhost", - port: 3000, - }, - production: { - defaults, - host: "api.example.com", - port: 443, - }, - servers: [ - { name: "server1", url: "https://api1.example.com" }, - { name: "server2", url: "https://api2.example.com" }, - ], - features: { - enabled: ["auth", "logging", "metrics"], - disabled: ["experimental"], - }, -}; - -// Generate readable YAML with 2-space indentation -const yaml = Bun.YAML.stringify(config, null, 2); -await Bun.write("config.yaml", yaml); - -// The output is valid YAML that parses back to the original object -import { deepEqual } from "node:assert"; -deepEqual(config, Bun.YAML.parse(yaml)); -``` - -```yaml output.yaml icon="file-code" -defaults: - &defaults - timeout: 30000 - retries: 3 -development: - defaults: - *defaults - host: localhost - port: 3000 -production: - defaults: - *defaults - host: api.example.com - port: 443 -servers: - - name: server1 - url: https://api1.example.com - - name: server2 - url: https://api2.example.com -features: - enabled: - - auth - - logging - - metrics - disabled: - - experimental -``` - - -### Bundler Integration - -When you import YAML files in your application and bundle it with Bun, the YAML is parsed at build time and included as a JavaScript module: - -```bash terminal icon="terminal" -bun build app.ts --outdir=dist -``` - -This means: - -- Zero runtime YAML parsing overhead in production -- Smaller bundle sizes -- Tree-shaking support for unused configuration (named imports) - -### Dynamic Imports - -YAML files can be dynamically imported, useful for loading configuration on demand: - -```ts Load configuration based on environment -const env = process.env.NODE_ENV || "development"; -const config = await import(`./configs/${env}.yaml`); - -// Load user-specific settings -async function loadUserSettings(userId: string) { - try { - const settings = await import(`./users/${userId}/settings.yaml`); - return settings.default; - } catch { - return await import("./users/default-settings.yaml"); - } -} -``` +--- +title: YAML +description: Use Bun's built-in support for YAML files through both runtime APIs and bundler integration +--- + +In Bun, YAML is a first-class citizen alongside JSON and TOML. You can: + +- Parse YAML strings with `Bun.YAML.parse` and stringify objects with `Bun.YAML.stringify` +- `import` & `require` YAML files as modules at runtime (including hot reloading & watch mode support) +- `import` & `require` YAML files in frontend apps via bun's bundler + +--- + +## Conformance + +Bun's YAML parser currently passes over 90% of the official YAML test suite. While we're actively working on reaching 100% conformance, the current implementation covers the vast majority of real-world use cases. The parser is written in Zig for optimal performance and is continuously being improved. + +--- + +## Runtime API + +### `Bun.YAML.parse()` + +Parse a YAML string into a JavaScript object. + +```ts +import { YAML } from "bun"; +const text = ` +name: John Doe +age: 30 +email: john@example.com +hobbies: + - reading + - coding + - hiking +`; + +const data = YAML.parse(text); +console.log(data); +// { +// name: "John Doe", +// age: 30, +// email: "john@example.com", +// hobbies: ["reading", "coding", "hiking"] +// } +``` + +#### Multi-document YAML + +When parsing YAML with multiple documents (separated by `---`), `Bun.YAML.parse()` returns an array: + +```ts +const multiDoc = ` +--- +name: Document 1 +--- +name: Document 2 +--- +name: Document 3 +`; + +const docs = Bun.YAML.parse(multiDoc); +console.log(docs); +// [ +// { name: "Document 1" }, +// { name: "Document 2" }, +// { name: "Document 3" } +// ] +``` + +#### Supported YAML Features + +Bun's YAML parser supports the full YAML 1.2 specification, including: + +- **Scalars**: strings, numbers, booleans, null values +- **Collections**: sequences (arrays) and mappings (objects) +- **Anchors and Aliases**: reusable nodes with `&` and `*` +- **Tags**: type hints like `!!str`, `!!int`, `!!float`, `!!bool`, `!!null` +- **Multi-line strings**: literal (`|`) and folded (`>`) scalars +- **Comments**: using `#` +- **Directives**: `%YAML` and `%TAG` + +```ts +const yaml = ` +# Employee record +employee: &emp + name: Jane Smith + department: Engineering + skills: + - JavaScript + - TypeScript + - React + +manager: *emp # Reference to employee + +config: !!str 123 # Explicit string type + +description: | + This is a multi-line + literal string that preserves + line breaks and spacing. + +summary: > + This is a folded string + that joins lines with spaces + unless there are blank lines. +`; + +const data = Bun.YAML.parse(yaml); +``` + +#### Error Handling + +`Bun.YAML.parse()` throws a `SyntaxError` if the YAML is invalid: + +```ts +try { + Bun.YAML.parse("invalid: yaml: content:"); +} catch (error) { + console.error("Failed to parse YAML:", error.message); +} +``` + +### `Bun.YAML.stringify()` + +Convert a JavaScript object into a YAML string. + +```ts +import { YAML } from "bun"; + +const obj = { + name: "John Doe", + age: 30, + email: "john@example.com", + hobbies: ["reading", "coding", "hiking"], +}; + +const yaml = Bun.YAML.stringify(obj, null, 2); +console.log(yaml); +// name: John Doe +// age: 30 +// email: john@example.com +// hobbies: +// - reading +// - coding +// - hiking +``` + +The signature is similar to `JSON.stringify()`: + +```ts +Bun.YAML.stringify(value, replacer?, space?) +``` + +The `space` parameter controls indentation (default: 2). With `space: 0`, YAML outputs in compact flow style on a single line: + +```ts +const compact = Bun.YAML.stringify(obj, null, 0); +// {name: John Doe,age: 30,email: john@example.com,hobbies: [reading,coding,hiking]} +``` + +--- + +## Module Import + +### ES Modules + +You can import YAML files directly as ES modules. The YAML content is parsed and made available as both default and named exports: + +```yaml config.yaml +database: + host: localhost + port: 5432 + name: myapp + +redis: + host: localhost + port: 6379 + +features: + auth: true + rateLimit: true + analytics: false +``` + +#### Default Import + +```ts app.ts icon="/icons/typescript.svg" +import config from "./config.yaml"; + +console.log(config.database.host); // "localhost" +console.log(config.redis.port); // 6379 +``` + +#### Named Imports + +You can destructure top-level YAML properties as named imports: + +```ts app.ts icon="/icons/typescript.svg" +import { database, redis, features } from "./config.yaml"; + +console.log(database.host); // "localhost" +console.log(redis.port); // 6379 +console.log(features.auth); // true +``` + +Or combine both: + +```ts app.ts icon="/icons/typescript.svg" +import config, { database, features } from "./config.yaml"; + +// Use the full config object +console.log(config); + +// Or use specific parts +if (features.rateLimit) { + setupRateLimiting(database); +} +``` + +### CommonJS + +YAML files can also be required in CommonJS: + +```ts app.ts icon="/icons/typescript.svg" +const config = require("./config.yaml"); +console.log(config.database.name); // "myapp" + +// Destructuring also works +const { database, redis } = require("./config.yaml"); +console.log(database.port); // 5432 +``` + +### TypeScript + +Unlike JSON files, TypeScript doesn't automatically type YAML imports. Add type definitions by creating a `.d.ts` file with the same name as your YAML file: + +```ts config.yaml.d.ts icon="/icons/typescript.svg" +const contents: { + database: { + host: string; + port: number; + name: string; + }; + server: { + port: number; + timeout: number; + }; + features: { + auth: boolean; + rateLimit: boolean; + }; +}; + +export = contents; +``` + +--- + +## Hot Reloading with YAML + +One of the most powerful features of Bun's YAML support is hot reloading. When you run your application with `bun --hot`, changes to YAML files are automatically detected and reloaded without closing connections + +### Configuration Hot Reloading + +```yaml config.yaml +server: + port: 3000 + host: localhost + +features: + debug: true + verbose: false +``` + +```ts server.ts icon="/icons/typescript.svg" +import { server, features } from "./config.yaml"; + +console.log(`Starting server on ${server.host}:${server.port}`); + +if (features.debug) { + console.log("Debug mode enabled"); +} + +// Your server code here +Bun.serve({ + port: server.port, + hostname: server.host, + fetch(req) { + if (features.verbose) { + console.log(`${req.method} ${req.url}`); + } + return new Response("Hello World"); + }, +}); +``` + +Run with hot reloading: + +```bash terminal icon="terminal" +bun --hot server.ts +``` + +Now when you modify `config.yaml`, the changes are immediately reflected in your running application. This is perfect for: + +- Adjusting configuration during development +- Testing different settings without restarts +- Live debugging with configuration changes +- Feature flag toggling + +--- + +## Configuration Management + +### Environment-Based Configuration + +YAML excels at managing configuration across different environments: + +```yaml config.yaml +defaults: &defaults + timeout: 5000 + retries: 3 + cache: + enabled: true + ttl: 3600 + +development: + <<: *defaults + api: + url: http://localhost:4000 + key: dev_key_12345 + logging: + level: debug + pretty: true + +staging: + <<: *defaults + api: + url: https://staging-api.example.com + key: ${STAGING_API_KEY} + logging: + level: info + pretty: false + +production: + <<: *defaults + api: + url: https://api.example.com + key: ${PROD_API_KEY} + cache: + enabled: true + ttl: 86400 + logging: + level: error + pretty: false +``` + +```ts app.ts icon="/icons/typescript.svg" +import configs from "./config.yaml"; + +const env = process.env.NODE_ENV || "development"; +const config = configs[env]; + +// Environment variables in YAML values can be interpolated +function interpolateEnvVars(obj: any): any { + if (typeof obj === "string") { + return obj.replace(/\${(\w+)}/g, (_, key) => process.env[key] || ""); + } + if (typeof obj === "object") { + for (const key in obj) { + obj[key] = interpolateEnvVars(obj[key]); + } + } + return obj; +} + +export default interpolateEnvVars(config); +``` + +### Feature Flags Configuration + +```yaml features.yaml +features: + newDashboard: + enabled: true + rolloutPercentage: 50 + allowedUsers: + - admin@example.com + - beta@example.com + + experimentalAPI: + enabled: false + endpoints: + - /api/v2/experimental + - /api/v2/beta + + darkMode: + enabled: true + default: auto # auto, light, dark +``` + +```ts feature-flags.ts icon="/icons/typescript.svg" +import { features } from "./features.yaml"; + +export function isFeatureEnabled(featureName: string, userEmail?: string): boolean { + const feature = features[featureName]; + + if (!feature?.enabled) { + return false; + } + + // Check rollout percentage + if (feature.rolloutPercentage < 100) { + const hash = hashCode(userEmail || "anonymous"); + if (hash % 100 >= feature.rolloutPercentage) { + return false; + } + } + + // Check allowed users + if (feature.allowedUsers && userEmail) { + return feature.allowedUsers.includes(userEmail); + } + + return true; +} + +// Use with hot reloading to toggle features in real-time +if (isFeatureEnabled("newDashboard", user.email)) { + renderNewDashboard(); +} else { + renderLegacyDashboard(); +} +``` + +### Database Configuration + +```yaml database.yaml icon="yaml" +connections: + primary: + type: postgres + host: ${DB_HOST:-localhost} + port: ${DB_PORT:-5432} + database: ${DB_NAME:-myapp} + username: ${DB_USER:-postgres} + password: ${DB_PASS} + pool: + min: 2 + max: 10 + idleTimeout: 30000 + + cache: + type: redis + host: ${REDIS_HOST:-localhost} + port: ${REDIS_PORT:-6379} + password: ${REDIS_PASS} + db: 0 + + analytics: + type: clickhouse + host: ${ANALYTICS_HOST:-localhost} + port: 8123 + database: analytics + +migrations: + autoRun: ${AUTO_MIGRATE:-false} + directory: ./migrations + +seeds: + enabled: ${SEED_DB:-false} + directory: ./seeds +``` + +```ts db.ts icon="/icons/typescript.svg" +import { connections, migrations } from "./database.yaml"; +import { createConnection } from "./database-driver"; + +// Parse environment variables with defaults +function parseConfig(config: any) { + return JSON.parse( + JSON.stringify(config).replace( + /\${([^:-]+)(?::([^}]+))?}/g, + (_, key, defaultValue) => process.env[key] || defaultValue || "", + ), + ); +} + +const dbConfig = parseConfig(connections); + +export const db = await createConnection(dbConfig.primary); +export const cache = await createConnection(dbConfig.cache); +export const analytics = await createConnection(dbConfig.analytics); + +// Auto-run migrations if configured +if (parseConfig(migrations).autoRun === "true") { + await runMigrations(db, migrations.directory); +} +``` + +### Generating YAML Files + +You can use `Bun.YAML.stringify()` to programmatically create YAML configuration files. It handles complex data structures including nested objects, arrays, and objects within arrays. When you reference the same object multiple times, YAML automatically creates anchors (`&`) and aliases (`*`) to avoid duplication: + + +```ts generate-config.ts icon="/icons/typescript.svg" +import { YAML } from "bun"; + +const defaults = { +timeout: 30000, +retries: 3, +}; + +const config = { +defaults, +development: { +defaults, +host: "localhost", +port: 3000, +}, +production: { +defaults, +host: "api.example.com", +port: 443, +}, +servers: [ +{ name: "server1", url: "https://api1.example.com" }, +{ name: "server2", url: "https://api2.example.com" }, +], +features: { +enabled: ["auth", "logging", "metrics"], +disabled: ["experimental"], +}, +}; + +// Generate readable YAML with 2-space indentation +const yaml = Bun.YAML.stringify(config, null, 2); +await Bun.write("config.yaml", yaml); + +// The output is valid YAML that parses back to the original object +import { deepEqual } from "node:assert"; +deepEqual(config, Bun.YAML.parse(yaml)); + +```` + +```yaml output.yaml icon="file-code" +defaults: + &defaults + timeout: 30000 + retries: 3 +development: + defaults: + *defaults + host: localhost + port: 3000 +production: + defaults: + *defaults + host: api.example.com + port: 443 +servers: + - name: server1 + url: https://api1.example.com + - name: server2 + url: https://api2.example.com +features: + enabled: + - auth + - logging + - metrics + disabled: + - experimental +```` + + + +### Bundler Integration + +When you import YAML files in your application and bundle it with Bun, the YAML is parsed at build time and included as a JavaScript module: + +```bash terminal icon="terminal" +bun build app.ts --outdir=dist +``` + +This means: + +- Zero runtime YAML parsing overhead in production +- Smaller bundle sizes +- Tree-shaking support for unused configuration (named imports) + +### Dynamic Imports + +YAML files can be dynamically imported, useful for loading configuration on demand: + +```ts Load configuration based on environment +const env = process.env.NODE_ENV || "development"; +const config = await import(`./configs/${env}.yaml`); + +// Load user-specific settings +async function loadUserSettings(userId: string) { + try { + const settings = await import(`./users/${userId}/settings.yaml`); + return settings.default; + } catch { + return await import("./users/default-settings.yaml"); + } +} +```