Skip to content
Merged
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
5fd6735
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 23, 2026
1bd8ad4
use esm module info in source provider
alii Jan 23, 2026
6c7ef4d
record top level decl in the parser + impl the cached transpiled module
alii Jan 23, 2026
3695007
revert files broken from a merge (whoops)
alii Jan 23, 2026
2698887
fix: add debug logging for module_info deserialization failures
alii Jan 23, 2026
7280a9a
move @import statements to bottom of file per project conventions
alii Jan 23, 2026
314b9d4
fix: set parse_error on module_info finalization failure
alii Jan 23, 2026
a8b8610
fix: derive VarKind from statement kind in module_info recording
alii Jan 23, 2026
8fd56a4
fix: prevent ArrayList leak in serializeModuleInfo
alii Jan 23, 2026
22855ec
fix UB: use gpa.destroy(res) instead of res.deinit() in errdefer
alii Jan 23, 2026
9db3dbc
move inline @import of DiffFormatter to bottom of file
alii Jan 23, 2026
ff5fa80
use info.destroy() to honor the stored allocator in ModuleInfo
alii Jan 23, 2026
687cfc8
free ModuleInfo after serialization to avoid leak
alii Jan 23, 2026
a8d47d5
fix a build err
alii Jan 23, 2026
f6c5700
temp
alii Jan 23, 2026
9630397
Merge branch 'main' of github.com:oven-sh/bun into ali/esm-bytecode
alii Jan 26, 2026
56ea8da
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 26, 2026
26e4b98
missing module_info plumbing
alii Jan 26, 2026
b515c2b
Fix potential OOB access in addRequestedModuleHostDefined
alii Jan 26, 2026
86479e3
Handle OOM errors in module_info fix-up instead of silently ignoring …
alii Jan 26, 2026
1e15c5d
Use per-chunk public_path when resolving module_info cross-chunk imports
alii Jan 26, 2026
210ea88
Skip unused/type-only imports in postProcessJSChunk module info
alii Jan 26, 2026
716ed5a
Revert "Skip unused/type-only imports in postProcessJSChunk module info"
alii Jan 26, 2026
206c24b
plumbing
alii Jan 26, 2026
f755caf
plumbing
alii Jan 26, 2026
fc9733f
Merge branch 'ali/esm-bytecode' of github.com:oven-sh/bun into ali/es…
alii Jan 26, 2026
6f137a2
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 26, 2026
18093e4
use bun.StringHashMap
alii Jan 27, 2026
dfb90a5
sort star exports deterministically & remove duplicate includes
alii Jan 27, 2026
487787c
address some feedback in js_printer.zig
alii Jan 27, 2026
162f80e
tests + type re-export tests, some fixes
alii Jan 27, 2026
7189f22
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 27, 2026
ec029b1
matrix test for permuations of splitting, dynamic imports and bytecode
alii Jan 27, 2026
9714dee
fix import meta
alii Jan 27, 2026
e0a3177
use ArrayListUnmanaged
alii Jan 27, 2026
c7ec692
address jarred feedback
alii Jan 27, 2026
b7b36f5
Merge branch 'main' of github.com:oven-sh/bun into ali/esm-bytecode
alii Jan 27, 2026
4e25e35
unify the BadModuleInfo error handling
alii Jan 27, 2026
69e9fed
fix a more serious leak (fixes require-cache.test.ts)
alii Jan 27, 2026
ad5fa18
make this much easier to read
alii Jan 27, 2026
f8854f8
remove {todo: "true"} import attribute
alii Jan 28, 2026
567cca9
fix module_info leak on printWithSourceMap error
alii Jan 28, 2026
68e0a42
address review comments in type-export.test.ts
alii Jan 28, 2026
94f3eb1
trigger
alii Jan 28, 2026
79c699b
Merge branch 'main' into ali/esm-bytecode
alii Jan 28, 2026
7991519
Merge branch 'main' of github.com:oven-sh/bun into ali/esm-bytecode
alii Jan 28, 2026
a7c3b39
Merge branch 'ali/esm-bytecode' of github.com:oven-sh/bun into ali/es…
alii Jan 28, 2026
91324d8
update the windows friendly build-jsc script
alii Jan 28, 2026
f5e4c87
windows: `B:/~BUN` → `B:/BUN`
alii Jan 28, 2026
55691d1
try prefix with "base_public_path_with_default_suffix"
alii Jan 28, 2026
a6d95df
Revert "windows: `B:/~BUN` → `B:/BUN`"
alii Jan 29, 2026
6eac109
Revert "try prefix with "base_public_path_with_default_suffix""
alii Jan 29, 2026
cc7a762
Reapply "try prefix with "base_public_path_with_default_suffix""
alii Jan 29, 2026
d042f19
testing
alii Jan 29, 2026
0fc5b50
Merge branch 'main' of github.com:oven-sh/bun into ali/esm-bytecode
alii Jan 29, 2026
72503b7
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 29, 2026
0197f83
revert build-jsc.ts
alii Jan 29, 2026
29c02b3
missing .md
alii Jan 29, 2026
a4e8c04
trace
alii Jan 29, 2026
d4d8e11
standalone bytecode cache misses on Windows - origin URL mismatch bet…
alii Jan 29, 2026
27cdb83
Remove verbose bytecode cache debug logs
Jan 29, 2026
0995a0e
semi address review comments
alii Jan 30, 2026
5671e7b
Update test/js/bun/typescript/type-export.test.ts
alii Jan 30, 2026
1815083
only enable esm module info in standalone module graph for now
alii Jan 30, 2026
341e1ee
skip `run` mode for type-export.test.ts since we disabled module info…
alii Jan 30, 2026
93b8a2d
dont break the assumption that cjs is the default format under --byte…
alii Jan 30, 2026
b5d64cf
use --format=esm
alii Jan 30, 2026
a1f27a7
window compile target with --windows-x flag should fail on non window…
alii Jan 30, 2026
48adee7
Revert "window compile target with --windows-x flag should fail on no…
alii Jan 30, 2026
712b637
Reapply "window compile target with --windows-x flag should fail on n…
alii Jan 30, 2026
519d9dc
store the esm_record_hash (claude feedback 1)
alii Jan 30, 2026
1c0d6eb
skip this check
alii Jan 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions docs/bundler/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1354,22 +1354,22 @@ In the JavaScript API, `metafile` accepts several forms:
```ts title="build.ts" icon="/icons/typescript.svg"
// Boolean — include metafile in the result object
await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
entrypoints: ["./src/index.ts"],
outdir: "./dist",
metafile: true,
});

// String — write JSON metafile to a specific path
await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
entrypoints: ["./src/index.ts"],
outdir: "./dist",
metafile: "./dist/meta.json",
});

// Object — specify separate paths for JSON and markdown output
await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
entrypoints: ["./src/index.ts"],
outdir: "./dist",
metafile: {
json: "./dist/meta.json",
markdown: "./dist/meta.md",
Expand Down
22 changes: 11 additions & 11 deletions docs/project/benchmarking.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,12 @@ bun --cpu-prof --cpu-prof-name my-profile.cpuprofile script.js
bun --cpu-prof --cpu-prof-dir ./profiles script.js
```

| Flag | Description |
| ---------------------------- | -------------------------------------------------------- |
| Flag | Description |
| ---------------------------- | ----------------------------------------------------------- |
| `--cpu-prof` | Generate a `.cpuprofile` JSON file (Chrome DevTools format) |
| `--cpu-prof-md` | Generate a markdown CPU profile (grep/LLM-friendly) |
| `--cpu-prof-name <filename>` | Set output filename |
| `--cpu-prof-dir <dir>` | Set output directory |
| `--cpu-prof-md` | Generate a markdown CPU profile (grep/LLM-friendly) |
| `--cpu-prof-name <filename>` | Set output filename |
| `--cpu-prof-dir <dir>` | Set output directory |

## Heap profiling

Expand Down Expand Up @@ -288,9 +288,9 @@ bun --heap-prof --heap-prof-name my-snapshot.heapsnapshot script.js
bun --heap-prof --heap-prof-dir ./profiles script.js
```

| Flag | Description |
| ----------------------------- | --------------------------------------------------------- |
| `--heap-prof` | Generate a V8 `.heapsnapshot` file on exit |
| `--heap-prof-md` | Generate a markdown heap profile on exit |
| `--heap-prof-name <filename>` | Set output filename |
| `--heap-prof-dir <dir>` | Set output directory |
| Flag | Description |
| ----------------------------- | ------------------------------------------ |
| `--heap-prof` | Generate a V8 `.heapsnapshot` file on exit |
| `--heap-prof-md` | Generate a markdown heap profile on exit |
| `--heap-prof-name <filename>` | Set output filename |
| `--heap-prof-dir <dir>` | Set output directory |
18 changes: 9 additions & 9 deletions docs/runtime/utils.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -902,19 +902,19 @@ Bun.wrapAnsi("\u001b[31mThe quick brown fox jumps over the lazy dog\u001b[0m", 2

```ts
Bun.wrapAnsi("Hello World", 5, {
hard: true, // Break words that exceed column width (default: false)
wordWrap: true, // Wrap at word boundaries (default: true)
trim: true, // Trim leading/trailing whitespace per line (default: true)
hard: true, // Break words that exceed column width (default: false)
wordWrap: true, // Wrap at word boundaries (default: true)
trim: true, // Trim leading/trailing whitespace per line (default: true)
ambiguousIsNarrow: true, // Treat ambiguous-width characters as narrow (default: true)
});
```

| Option | Default | Description |
| --- | --- | --- |
| `hard` | `false` | If `true`, break words in the middle if they exceed the column width. |
| `wordWrap` | `true` | If `true`, wrap at word boundaries. If `false`, only break at explicit newlines. |
| `trim` | `true` | If `true`, trim leading and trailing whitespace from each line. |
| `ambiguousIsNarrow` | `true` | If `true`, treat ambiguous-width Unicode characters as 1 column wide. If `false`, treat them as 2 columns wide. |
| Option | Default | Description |
| ------------------- | ------- | --------------------------------------------------------------------------------------------------------------- |
| `hard` | `false` | If `true`, break words in the middle if they exceed the column width. |
| `wordWrap` | `true` | If `true`, wrap at word boundaries. If `false`, only break at explicit newlines. |
| `trim` | `true` | If `true`, trim leading and trailing whitespace from each line. |
| `ambiguousIsNarrow` | `true` | If `true`, treat ambiguous-width Unicode characters as 1 column wide. If `false`, treat them as 2 columns wide. |

TypeScript definition:

Expand Down
3 changes: 3 additions & 0 deletions src/OutputFile.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ hash: u64 = 0,
is_executable: bool = false,
source_map_index: u32 = std.math.maxInt(u32),
bytecode_index: u32 = std.math.maxInt(u32),
Comment thread
alii marked this conversation as resolved.
module_info_index: u32 = std.math.maxInt(u32),
output_kind: jsc.API.BuildArtifact.OutputKind,
/// Relative
dest_path: []const u8 = "",
Expand Down Expand Up @@ -210,6 +211,7 @@ pub const Options = struct {
hash: ?u64 = null,
source_map_index: ?u32 = null,
bytecode_index: ?u32 = null,
module_info_index: ?u32 = null,
output_path: string,
source_index: Index.Optional = .none,
size: ?usize = null,
Expand Down Expand Up @@ -251,6 +253,7 @@ pub fn init(options: Options) OutputFile {
.hash = options.hash orelse 0,
.output_kind = options.output_kind,
.bytecode_index = options.bytecode_index orelse std.math.maxInt(u32),
.module_info_index = options.module_info_index orelse std.math.maxInt(u32),
.source_map_index = options.source_map_index orelse std.math.maxInt(u32),
.is_executable = options.is_executable,
.value = switch (options.data) {
Expand Down
34 changes: 34 additions & 0 deletions src/StandaloneModuleGraph.zig
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ pub const StandaloneModuleGraph = struct {
contents: Schema.StringPointer = .{},
sourcemap: Schema.StringPointer = .{},
bytecode: Schema.StringPointer = .{},
module_info: Schema.StringPointer = .{},
/// The file path used when generating bytecode (e.g., "B:/~BUN/root/app.js").
/// Must match exactly at runtime for bytecode cache hits.
bytecode_origin_path: Schema.StringPointer = .{},
encoding: Encoding = .latin1,
loader: bun.options.Loader = .file,
module_format: ModuleFormat = .none,
Expand Down Expand Up @@ -159,6 +163,10 @@ pub const StandaloneModuleGraph = struct {
encoding: Encoding = .binary,
wtf_string: bun.String = bun.String.empty,
bytecode: []u8 = "",
module_info: []u8 = "",
/// The file path used when generating bytecode (e.g., "B:/~BUN/root/app.js").
/// Must match exactly at runtime for bytecode cache hits.
bytecode_origin_path: []const u8 = "",
module_format: ModuleFormat = .none,
side: FileSide = .server,

Expand Down Expand Up @@ -333,6 +341,8 @@ pub const StandaloneModuleGraph = struct {
else
.none,
.bytecode = if (module.bytecode.length > 0) @constCast(sliceTo(raw_bytes, module.bytecode)) else &.{},
.module_info = if (module.module_info.length > 0) @constCast(sliceTo(raw_bytes, module.module_info)) else &.{},
.bytecode_origin_path = if (module.bytecode_origin_path.length > 0) sliceToZ(raw_bytes, module.bytecode_origin_path) else "",
.module_format = module.module_format,
.side = module.side,
},
Expand Down Expand Up @@ -382,6 +392,8 @@ pub const StandaloneModuleGraph = struct {
} else if (output_file.output_kind == .bytecode) {
// Allocate up to 256 byte alignment for bytecode
string_builder.cap += (output_file.value.buffer.bytes.len + 255) / 256 * 256 + 256;
} else if (output_file.output_kind == .module_info) {
string_builder.cap += output_file.value.buffer.bytes.len;
} else {
if (entry_point_id == null) {
if (output_file.side == null or output_file.side.? == .server) {
Expand Down Expand Up @@ -477,6 +489,19 @@ pub const StandaloneModuleGraph = struct {
}
};

// Embed module_info for ESM bytecode
const module_info: StringPointer = brk: {
if (output_file.module_info_index != std.math.maxInt(u32)) {
const mi_bytes = output_files[output_file.module_info_index].value.buffer.bytes;
const offset = string_builder.len;
const writable = string_builder.writable();
@memcpy(writable[0..mi_bytes.len], mi_bytes[0..mi_bytes.len]);
string_builder.len += mi_bytes.len;
break :brk StringPointer{ .offset = @truncate(offset), .length = @truncate(mi_bytes.len) };
}
break :brk .{};
};

if (comptime bun.Environment.is_canary or bun.Environment.isDebug) {
if (bun.env_var.BUN_FEATURE_FLAG_DUMP_CODE.get()) |dump_code_dir| {
const buf = bun.path_buffer_pool.get();
Expand All @@ -498,6 +523,13 @@ pub const StandaloneModuleGraph = struct {
}
}

// When there's bytecode, store the bytecode output file's path as bytecode_origin_path.
// This path was used to generate the bytecode cache and must match at runtime.
const bytecode_origin_path: StringPointer = if (output_file.bytecode_index != std.math.maxInt(u32))
string_builder.appendCountZ(output_files[output_file.bytecode_index].dest_path)
else
.{};

var module = CompiledModuleGraphFile{
.name = string_builder.fmtAppendCountZ("{s}{s}", .{
prefix,
Expand All @@ -515,6 +547,8 @@ pub const StandaloneModuleGraph = struct {
else => .none,
} else .none,
.bytecode = bytecode,
.module_info = module_info,
.bytecode_origin_path = bytecode_origin_path,
.side = switch (output_file.side orelse .server) {
.server => .server,
.client => .client,
Expand Down
Loading