Skip to content

Conversation

@remorses
Copy link
Contributor

@remorses remorses commented Dec 23, 2025

Changes

  • Upgrade from Zig 0.14.x to 0.15.2
  • Add ghostty-vt as a dependency for terminal emulation
  • Update build.zig for Zig 0.15 API (createModule, standardOptimizeOption, etc.)
  • Use -gnu suffix for Linux targets to fix PIC linker errors when cross-compiling
  • Update CI workflows (build-core.yml, build-native.yml) to use Zig 0.15.2
  • Update all zig source files for 0.15 compatibility:
    • callconv(.C)callconv(.c)
    • std.ArrayListstd.ArrayListUnmanaged with explicit allocator
    • Writer/BufferedWriter API changes

Testing

Cross-compiled Linux binaries (both x64 and arm64) were tested inside an OrbStack Linux VM. The full rendering pipeline works correctly - created a test that renders a multi-panel layout with boxes, text, and different border styles (rounded, single, double). The TUI output renders properly and the renderer starts/stops cleanly with exit code 0.

- update build.zig for zig 0.15 API (createModule, standardOptimizeOption)
- add ghostty-vt dependency for terminal emulation
- use -gnu suffix for linux targets to fix PIC linker errors
- update CI workflows to use zig 0.15.2
- update all zig source files for 0.15 compatibility
…inux

- Update React and Solid workflows to use Zig 0.15.2 (required by ghostty-vt)
- Skip macOS targets when building on non-macOS hosts (ghostty's apple-sdk
  doesn't support cross-compilation from Linux)
- Update TypeScript build script to handle missing platform builds gracefully
- Add mitchellh/zig-build-macos-sdk dependency (official SDK used by Ghostty)
- Configure SDK paths on module before loading ghostty dependencies
- Update to latest ghostty commit
- Remove skip logic for macOS targets since SDK is now provided
Native binaries for all platforms are built in the release workflow
(build-native.yml on macOS). PR checks only need to build the TypeScript
library and run tests.
macOS can cross-compile to all platforms (Linux, Windows, macOS).
This avoids the complexity of setting up macOS SDK on Linux runners.
- By default, zig build now only builds for the native platform
- Add -Dall option to zig build for building all platforms
- Add --all flag to TypeScript build script
- Update release workflow to use --all for cross-compilation

This allows Linux users to run `bun run build` without failing on macOS targets.
- ArrayList.init(allocator) → ArrayListUnmanaged with allocator per-method
- std.fmt.formatIntBuf → std.fmt.bufPrint
- std.fmt.formatInt → writer.print
- std.zon.parse.Status removed, use fromSlice directly
@remorses remorses marked this pull request as ready for review December 27, 2025 20:32
Copilot AI review requested due to automatic review settings December 27, 2025 20:32
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR upgrades the Zig compiler from version 0.14.x to 0.15.2 and adds the ghostty-vt dependency for terminal emulation. The upgrade requires extensive changes throughout the codebase to adapt to API changes in Zig 0.15.

Key Changes

  • Upgraded Zig version from 0.14.1 to 0.15.2 across all configuration files
  • Added ghostty-vt dependency for terminal emulation support
  • Migrated from std.ArrayList to std.ArrayListUnmanaged with explicit allocator passing throughout the codebase
  • Updated calling convention syntax from callconv(.C) to callconv(.c)
  • Adapted to new Writer/BufferedWriter API that uses buffer-based writers with .interface field access
  • Updated build.zig to use new Zig 0.15 APIs (createModule, standardOptimizeOption)
  • Added -gnu suffix for Linux targets to fix PIC linker errors with C++ dependencies

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
.zig-version Updated version from 0.14.1 to 0.15.2
build.zig.zon Updated minimum Zig version, updated uucode dependency URL, added ghostty dependency
build.zig Refactored build system for Zig 0.15 API, added support for native/all target building, updated target definitions with -gnu suffix
lib.zig Updated callconv syntax, added ghostty-vt import with temporary export function
logger.zig, event-bus.zig Updated callconv from .C to .c
utf8.zig Migrated all Result structs to use ArrayListUnmanaged with explicit allocator
text-buffer.zig Converted ArrayList to ArrayListUnmanaged, added allocator to return types
text-buffer-segment.zig Updated GraphemeInfo collection to use ArrayListUnmanaged
rope.zig Extensive ArrayListUnmanaged migration, updated collect and nodeToText functions
renderer.zig Replaced BufferedWriter with buffer-based writer approach, migrated stat sample arrays to ArrayListUnmanaged
buffer.zig Updated scissor and opacity stacks to ArrayListUnmanaged
ansi.zig Replaced std.fmt.format with writer.print, manual loop for writeByteNTimes
syntax-style.zig Updated formatInt to use writer.print
edit-buffer.zig Added allocator parameter to deinit call
All test files Updated test setup to use ArrayListUnmanaged pattern
scripts/build.ts Added --all flag support, changed error behavior to skip missing platforms
CI workflows Updated Zig version to 0.15.2, changed some runners to macos-latest, updated test commands

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kommander
Copy link
Collaborator

It does currently not build/run for windows because of some Ghostty issues, needs some work. @Hona is checking.

@remorses

This comment was marked as outdated.

@kommander
Copy link
Collaborator

Maybe we can take out the ghostty-vt dependency from this PR and let it only be the 0.15.2 migration and we can bring in the ghostty dep with the terminal PR? Then @Hona has some time to check windows and we can move forward with some native changes.

@remorses
Copy link
Contributor Author

remorses commented Jan 3, 2026

I tested the cross compiled binary to be working on Windows here (only 4 tests fail because of timing issues unrelated)

zig build still fails on Windows because of some Zig 0.15 bugs about caching on different modules and another issue with ftruncate

If no one uses Windows in the team I think we can merge and debug why zig in Windows does not build later on.

@remorses
Copy link
Contributor Author

remorses commented Jan 3, 2026

Windows native build now works with two fixes:

  1. ghostty stdout fix - PR submitted: fix: use flush instead of end on stdout in code generators for Windows compatibility ghostty-org/ghostty#10150
    The ghostty code generators crash on Windows because stdout.end() tries to truncate a pipe handle. Fix uses flush() instead.

  2. Zig cache directory workaround - On Windows CI, the working directory and default cache are on different drives (D: vs C:), causing Zig 0.15.2 to crash (Step.Run does not account for child cwd and cache path being on different drives ziglang/zig#25805). Workaround is to pass cache dir explicitly:

zig build -Doptimize=ReleaseFast --cache-dir .zig-cache --global-cache-dir .zig-cache

Windows CI run with both fixes (2879 tests pass): https://github.com/remorses/opentui/actions/runs/20671299561/job/59352503875

I can switch the ghostty dependency to my fork to make it build on Windows, do I switch it @kommander ?

@kommander
Copy link
Collaborator

Can we just move the ghostty-vt dep to #440 and bring it in there so we can get this through? I don't want to risk opencode windows support, which is already subpar.

@remorses
Copy link
Contributor Author

remorses commented Jan 6, 2026

ghostty has been removed from this branch but still remains in the vterm-spans branch for terminal rendering work.

@remorses remorses changed the title Upgrade to Zig 0.15.2 with ghostty-vt dependency Upgrade to Zig 0.15.2 Jan 6, 2026
wrap-resize-perf.test.ts:
- The 'should scale linearly when wrap width changes' test was measuring
  cached performance instead of real work. measureMedian() runs 11 iterations
  but only the first call after setWrapWidth() does real work - the rest hit
  the cache (~0.001ms). Comparing sub-ms cached times gives unstable ratios
  due to noise (e.g. 0.003/0.0005 = 6x).
- Fix: measure the first (uncached) call for each width instead of using
  measureMedian. Also warmup with width=50 so all test widths cause cache miss.

Code.test.ts:
- The conceal test used fixed setTimeout(100ms/150ms) which wasn't enough in
  slow CI environments, causing lineCount to be 1 instead of 3.
- Fix: poll isHighlighting with timeout instead of fixed delays.
Same issue as TypeScript test - was measuring cached performance.
Removed measureMedianViewUpdate helper and measure first (uncached)
call for each width directly.
@remorses
Copy link
Contributor Author

remorses commented Jan 6, 2026

Flaky tests fixed

@kommander
Copy link
Collaborator

I tested on windows with a snapshot, seems to work fine. Going to merge.

@kommander kommander merged commit c85d932 into anomalyco:main Jan 6, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants