Skip to content

Conversation

@robobun
Copy link
Collaborator

@robobun robobun commented Nov 8, 2025

Summary

Improves YAML documentation by adding missing Bun.YAML.stringify() API documentation and clarifying TypeScript typing requirements.

This PR adds comprehensive documentation for the Bun.YAML.stringify() function which was previously undocumented, and clarifies how to add TypeScript types for YAML imports (which unlike JSON, are not automatic). All examples were tested with Bun to ensure accuracy.

Full Diff

diff --git a/docs/runtime/yaml.mdx b/docs/runtime/yaml.mdx
index 652a636cdd..4ccfe88c9c 100644
--- a/docs/runtime/yaml.mdx
+++ b/docs/runtime/yaml.mdx
@@ -5,7 +5,7 @@ description: Use Bun's built-in support for YAML files through both runtime APIs
 
 In Bun, YAML is a first-class citizen alongside JSON and TOML. You can:
 
-- Parse YAML strings with \`Bun.YAML.parse\`
+- 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
 
@@ -121,6 +121,44 @@ try {
 }
 ```
 
+### \`Bun.YAML.stringify()\`
+
+Convert a JavaScript object into a YAML string.
+
+```ts
+import { YAML } from "bun";
+
+const obj = {
+  name: "John Doe",
+  age: 30,
+  email: "[email protected]",
+  hobbies: ["reading", "coding", "hiking"],
+};
+
+const yaml = Bun.YAML.stringify(obj, null, 2);
+console.log(yaml);
+// name: John Doe
+// age: 30
+// email: [email protected]
+// 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: [email protected],hobbies: [reading,coding,hiking]}
+```
+
 ---
 
 ## Module Import
@@ -193,6 +231,30 @@ 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
@@ -435,6 +497,80 @@ if (parseConfig(migrations).autoRun === "true") {
 }
 ```
 
+### 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:
+
+<CodeGroup>
+```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
+```
+</CodeGroup>
+
 ### 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:

🤖 Generated with Claude Code

@robobun
Copy link
Collaborator Author

robobun commented Nov 8, 2025

Updated 2:49 PM PT - Nov 10th, 2025

@autofix-ci[bot], your commit 62d0b5a5b0c7d7493a9605af5248c1b3b320bde4 passed in Build #31427! 🎉


🧪   To try this PR locally:

bunx bun-pr 24497

That installs a local version of the PR into your bun-24497 executable, so you can run:

bun-24497 --bun

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 8, 2025

Walkthrough

Adds documentation, examples, and TypeScript typing guidance for the new public API Bun.YAML.stringify(value, replacer?, space?), integrates stringify usage into existing YAML docs and examples, and adds a "Generating YAML Files" workflow with usage and examples.

Changes

Cohort / File(s) Summary
YAML documentation
docs/runtime/yaml.mdx
Adds Bun.YAML.stringify(value, replacer?, space?) API docs and examples (default space = 2, space = 0 for compact flow), introduces a "Generating YAML Files" workflow with anchors/aliases and write/read examples, and updates Runtime API, bundling/dynamic-import, and TypeScript typing guidance to include stringify usage.

Possibly related PRs

Suggested reviewers

  • alii

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is well-structured with a clear summary of changes and includes the full diff. However, it does not follow the required template structure with 'What does this PR do?' and 'How did you verify your code works?' sections. Restructure the description to match the required template: add explicit 'What does this PR do?' and 'How did you verify your code works?' sections as specified in the repository template.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: adding Bun.YAML.stringify documentation, TypeScript types guidance, and comprehensive examples to the YAML documentation.

Comment @coderabbitai help to get the list of available commands and usage tips.

@robobun robobun force-pushed the claude/fix-yaml-docs branch from 484602c to b1f0f38 Compare November 8, 2025 04:21
@robobun robobun force-pushed the claude/fix-yaml-docs branch from ecb05ee to 2fe6aa7 Compare November 8, 2025 04:23
@robobun robobun force-pushed the claude/fix-yaml-docs branch from 259bf4f to 15c5fec Compare November 8, 2025 04:27
@robobun robobun force-pushed the claude/fix-yaml-docs branch from 15c5fec to 6fd6d66 Compare November 8, 2025 04:28
@robobun robobun force-pushed the claude/fix-yaml-docs branch 2 times, most recently from 89b01d6 to aade152 Compare November 8, 2025 04:29
@robobun robobun force-pushed the claude/fix-yaml-docs branch from 830622f to a5a116c Compare November 8, 2025 04:31
@robobun robobun force-pushed the claude/fix-yaml-docs branch from a898614 to 01771fa Compare November 8, 2025 04:34
@robobun robobun force-pushed the claude/fix-yaml-docs branch from 01771fa to 431a0b5 Compare November 8, 2025 04:35
@robobun robobun force-pushed the claude/fix-yaml-docs branch from 431a0b5 to ae1a6bd Compare November 8, 2025 04:36
Claude Bot and others added 2 commits November 9, 2025 05:24
Convert line endings from CRLF to LF to match repository standards and prevent unnecessary diffs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 267e6c8 and 3408c70.

📒 Files selected for processing (1)
  • docs/runtime/yaml.mdx (4 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: cirospaciari
Repo: oven-sh/bun PR: 22946
File: test/js/sql/sql.test.ts:195-202
Timestamp: 2025-09-25T22:07:13.851Z
Learning: PR oven-sh/bun#22946: JSON/JSONB result parsing updates (e.g., returning parsed arrays instead of legacy strings) are out of scope for this PR; tests keep current expectations with a TODO. Handle parsing fixes in a separate PR.
📚 Learning: 2025-09-25T22:07:13.851Z
Learnt from: cirospaciari
Repo: oven-sh/bun PR: 22946
File: test/js/sql/sql.test.ts:195-202
Timestamp: 2025-09-25T22:07:13.851Z
Learning: PR oven-sh/bun#22946: JSON/JSONB result parsing updates (e.g., returning parsed arrays instead of legacy strings) are out of scope for this PR; tests keep current expectations with a TODO. Handle parsing fixes in a separate PR.

Applied to files:

  • docs/runtime/yaml.mdx
📚 Learning: 2025-08-30T00:12:56.803Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/**/*.{js,ts} : Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test

Applied to files:

  • docs/runtime/yaml.mdx
📚 Learning: 2025-10-19T02:52:37.412Z
Learnt from: theshadow27
Repo: oven-sh/bun PR: 23798
File: packages/bun-otel/tsconfig.json:1-15
Timestamp: 2025-10-19T02:52:37.412Z
Learning: In the Bun repository, packages under packages/ (e.g., bun-otel) can follow a TypeScript-first pattern where package.json exports point directly to .ts files (not compiled .js files). Bun natively runs TypeScript, so consumers import .ts sources directly and receive full type information without needing compiled .d.ts declaration files. For such packages, adding "declaration": true or "outDir" in tsconfig.json is unnecessary and would break the export structure.
<!-- [remove_learning]
ceedde95-980e-4898-a2c6-40ff73913664

Applied to files:

  • docs/runtime/yaml.mdx
📚 Learning: 2025-10-19T02:44:46.354Z
Learnt from: theshadow27
Repo: oven-sh/bun PR: 23798
File: packages/bun-otel/context-propagation.test.ts:1-1
Timestamp: 2025-10-19T02:44:46.354Z
Learning: In the Bun repository, standalone packages under packages/ (e.g., bun-vscode, bun-inspector-protocol, bun-plugin-yaml, bun-plugin-svelte, bun-debug-adapter-protocol, bun-otel) co-locate their tests with package source code using *.test.ts files. This follows standard npm/monorepo patterns. The test/ directory hierarchy (test/js/bun/, test/cli/, test/js/node/) is reserved for testing Bun's core runtime APIs and built-in functionality, not standalone packages.

Applied to files:

  • docs/runtime/yaml.mdx
🔇 Additional comments (3)
docs/runtime/yaml.mdx (3)

8-8: Overview update is clear and concise. The addition of Bun.YAML.stringify alongside parse correctly signals both directions of YAML conversion to readers.


234-256: TypeScript guidance fills an important gap. The explanation that YAML imports lack automatic typing—unlike JSON—is clear, and the companion .d.ts file approach is the standard solution. The example type definitions are well-structured and complete.


500-543: Excellent comprehensive example demonstrating stringify and best practices. The code correctly demonstrates:

  • Shared object references converting to YAML anchors and aliases (a non-obvious feature users should know)
  • Proper API usage: Bun.YAML.stringify(config, null, 2) with readable indentation
  • File I/O via Bun.write()
  • Round-trip verification with deepEqual—a best practice for ensuring YAML fidelity

The indentation and structure are correct, and the accompanying output YAML (lines 545–569) correctly shows anchors and aliases as expected.

…stringify

Add note that the replacer parameter currently has no effect.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Bun.YAML.stringify(value, replacer?, space?)
```
The `replacer` parameter is currently not implemented and has no effect. The `space` parameter controls indentation (default: 2). With `space: 0`, YAML outputs in compact flow style on a single line:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a callout component in mintlify? That would be nice to have here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, let's wrap this in a <Note>

Copy link
Member

@alii alii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor note but lgtm otherwise


const yaml = Bun.YAML.stringify(obj, null, 2);
console.log(yaml);
// name: John Doe
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use a ```txt here to add a console output component

name: John Doe
age: 30
email: [email protected]
hobbies:
  - reading
  - coding
  - hiking

Bun.YAML.stringify(value, replacer?, space?)
```
The `replacer` parameter is currently not implemented and has no effect. The `space` parameter controls indentation (default: 2). With `space: 0`, YAML outputs in compact flow style on a single line:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, let's wrap this in a <Note>

```ts
const compact = Bun.YAML.stringify(obj, null, 0);
// {name: John Doe,age: 30,email: [email protected],hobbies: [reading,coding,hiking]}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrap in ```txt

{ name: "John Doe", age: 30, email: "[email protected]", hobbies: ["reading", "coding", "hiking"]}

- Use ```txt blocks for YAML input and console output
- Wrap replacer parameter note in <Note> component
- Complete incomplete sentence about hot reloading

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a3d4aa0 and 62d0b5a.

📒 Files selected for processing (1)
  • docs/runtime/yaml.mdx (5 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: cirospaciari
Repo: oven-sh/bun PR: 22946
File: test/js/sql/sql.test.ts:195-202
Timestamp: 2025-09-25T22:07:13.851Z
Learning: PR oven-sh/bun#22946: JSON/JSONB result parsing updates (e.g., returning parsed arrays instead of legacy strings) are out of scope for this PR; tests keep current expectations with a TODO. Handle parsing fixes in a separate PR.
📚 Learning: 2025-09-25T22:07:13.851Z
Learnt from: cirospaciari
Repo: oven-sh/bun PR: 22946
File: test/js/sql/sql.test.ts:195-202
Timestamp: 2025-09-25T22:07:13.851Z
Learning: PR oven-sh/bun#22946: JSON/JSONB result parsing updates (e.g., returning parsed arrays instead of legacy strings) are out of scope for this PR; tests keep current expectations with a TODO. Handle parsing fixes in a separate PR.

Applied to files:

  • docs/runtime/yaml.mdx
📚 Learning: 2025-08-30T00:12:56.803Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/**/*.{js,ts} : Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test

Applied to files:

  • docs/runtime/yaml.mdx
📚 Learning: 2025-10-19T02:52:37.412Z
Learnt from: theshadow27
Repo: oven-sh/bun PR: 23798
File: packages/bun-otel/tsconfig.json:1-15
Timestamp: 2025-10-19T02:52:37.412Z
Learning: In the Bun repository, packages under packages/ (e.g., bun-otel) can follow a TypeScript-first pattern where package.json exports point directly to .ts files (not compiled .js files). Bun natively runs TypeScript, so consumers import .ts sources directly and receive full type information without needing compiled .d.ts declaration files. For such packages, adding "declaration": true or "outDir" in tsconfig.json is unnecessary and would break the export structure.
<!-- [remove_learning]
ceedde95-980e-4898-a2c6-40ff73913664

Applied to files:

  • docs/runtime/yaml.mdx
📚 Learning: 2025-10-19T02:44:46.354Z
Learnt from: theshadow27
Repo: oven-sh/bun PR: 23798
File: packages/bun-otel/context-propagation.test.ts:1-1
Timestamp: 2025-10-19T02:44:46.354Z
Learning: In the Bun repository, standalone packages under packages/ (e.g., bun-vscode, bun-inspector-protocol, bun-plugin-yaml, bun-plugin-svelte, bun-debug-adapter-protocol, bun-otel) co-locate their tests with package source code using *.test.ts files. This follows standard npm/monorepo patterns. The test/ directory hierarchy (test/js/bun/, test/cli/, test/js/node/) is reserved for testing Bun's core runtime APIs and built-in functionality, not standalone packages.

Applied to files:

  • docs/runtime/yaml.mdx
🔇 Additional comments (4)
docs/runtime/yaml.mdx (4)

122-164: Stringify documentation is well-structured and comprehensive.

The section clearly parallels JSON.stringify(), documents the signature with proper examples, uses the <Note> component for the unimplemented replacer parameter, and demonstrates both readable (space: 2) and compact flow-style (space: 0) output. Code formatting with ```txt blocks for YAML output is correct per documentation guidelines.


238-260: TypeScript section provides clear YAML type definition guidance.

The .d.ts file pattern using export = is the correct approach for providing types that work with both ES module and CommonJS import styles. The example structure is clear and demonstrates the expected pattern.


26-44: YAML/JSON output formatting is correct.

Uses ```txt code blocks for YAML input and JSON object representation as intended, improving readability and alignment with documentation standards.


504-575: "Generating YAML Files" section demonstrates practical use of stringify with anchors/aliases.

The CodeGroup structure with TypeScript example and YAML output is effective. The example shows nested objects, arrays, and automatic anchor/alias generation. Round-trip verification via deepEqual() is a good practice to document. Note: Verify the import consistency issue flagged in line_ranges 510-547 is resolved, as it currently prevents this example from running correctly.

Comment on lines +510 to +547
```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));
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix import/usage inconsistency in the generate-config.ts example.

Line 511 imports { YAML } from "bun", but line 541 uses Bun.YAML.stringify() instead of YAML.stringify(). This code will fail at runtime with a reference error since YAML is imported but never used, and Bun is not defined in the script scope (Bun is a global in the CLI context, not available in regular scripts).

Apply one of these fixes:

Option 1 (recommended): Use the imported YAML

 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);
+const yaml = 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));
+deepEqual(config, YAML.parse(yaml));

Option 2: Remove unused import and use global Bun

-import { YAML } from "bun";

(Keep Bun.YAML.stringify() and Bun.YAML.parse() as-is on lines 541 and 546)

🤖 Prompt for AI Agents
In docs/runtime/yaml.mdx around lines 510 to 547, the example imports { YAML }
from "bun" but still calls Bun.YAML.stringify/parse and Bun.write, causing a
runtime reference error; fix it by using the imported symbols: change
Bun.YAML.stringify(...) to YAML.stringify(...) and Bun.YAML.parse(...) to
YAML.parse(...), replace Bun.write(...) with write(...) and update the import to
import { YAML, write } from "bun" so the example uses the imported APIs rather
than the undefined Bun global.

@RiskyMH RiskyMH added the docs Improvements or additions to documentation label Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude docs Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants