从34%到96%:移植计划完成 – 全息图v0.7.0
Hologram v0.7.0: Milestone release for Elixir-to-JavaScript porting initiative

原始链接: https://hologram.page/blog/porting-initiative-delivers-hologram-v0-7-0

## 全息图 v0.7.0:Elixir 在浏览器上的重大飞跃 全息图 v0.7.0 是将 Elixir 带到浏览器上的一个重要里程碑,Erlang 运行时覆盖率从 34% 跃升至 96%,Elixir 标准库准备就绪度从 74% 提升至 87%。本次发布是近 3 个月工作和超过 700 次提交的结果,移植了 150 个新的 Erlang 函数,完成了 238 个 Phase 1 函数中的 228 个。 这种扩展的覆盖范围解锁了大量 Elixir 标准库函数,可用于客户端使用,包括字符串处理、集合、集合、二进制操作、Unicode 处理、数学和文件路径操作。虽然与进程相关的模块已推迟到 Phase 2,但现在已经提供了构建全栈 Web 和基本本地优先应用程序所需的大部分功能。 除了移植之外,v0.7.0 还引入了更快的编译速度、跨平台设置、NixOS 兼容性以及与存储、不可变性、模板插值等相关的错误修复。本次发布还为未来的功能奠定了基础,例如客户端 ERTS 和改进的 ETS 基础设施。 衷心感谢 49 位贡献者,尤其是 @mward-sudo,感谢他们的奉献。 这项进展得益于 Curiosum 和 Erlang 生态系统基金会的赞助,以及慷慨的 GitHub 赞助者。

## 全息图 v0.7.0:Elixir 到 JavaScript 的进展 全息图,一个将 Elixir 编译为 JavaScript 的项目,已发布 v0.7.0 版本,达到一个重要里程碑。49 位贡献者移植了 19 个模块中的 150 个 Erlang 函数,客户端 Erlang 运行时覆盖率达到 96%,Elixir 标准库准备就绪度达到 87%。这意味着大多数标准 Elixir 函数——用于字符串处理、集合等——现在可以直接在浏览器中工作,从而实现全栈 Elixir 开发,并为本地优先应用程序铺平道路。 该项目优先考虑与 BEAM 运行时的语义对等性,选择在 JavaScript 中重新实现它,而不是使用 WASM 解释器,原因是包大小和 DOM 访问问题。虽然 Gleam 编译为可读的 JavaScript,开销最小,但全息图旨在实现服务器和客户端之间一致的行为。 该创建者欢迎提问并鼓励反馈,强调核心移植工作的同时,也在不断进行增强和修复。该项目正在获得关注,并为希望使用熟悉的语言构建基于浏览器的应用程序的 Elixir 开发者提供了一条有希望的途径。
相关文章

原文

Hologram v0.7.0 is a milestone release for the Elixir-to-JavaScript porting initiative. With 150 newly ported Erlang functions, Erlang runtime coverage has jumped from 34% to 96% - and overall Elixir standard library readiness has grown from 74% to 87%.

This release includes over 700 commits and represents nearly 3 months of focused work on expanding browser-side Elixir capabilities.

The Porting Initiative in Numbers

When we launched the porting initiative in November 2025, 92 Erlang functions had been ported to JavaScript - about 34% of what's needed for Phase 1. Since then, we've ported 150 more functions across 19 modules, pushing Erlang coverage to 96% (228 out of 238 Phase 1 functions done, 10 in progress, 0 remaining in the backlog). Elixir standard library readiness has grown from 74% to 87% (this metric reflects the average progress of Elixir stdlib functions based on how many of their underlying Erlang dependencies have been ported).

This means the vast majority of Elixir standard library functions needed for Phase 1 (full-stack web and basic local-first apps) now work in the browser. Functions for string manipulation, collections, math, sets, binary operations, Unicode normalization, file path handling, time operations, and more - all available client-side. Process-related modules remain deferred to Phase 2. Note that some functions in the client runtime reference may appear below 100% - this is because the compiler conservatively marks certain functions for client-side inclusion, but in practice they won't be needed for web applications. This will be addressed in following releases.

A huge thanks to all 49 contributors who took part in the porting initiative. Special shout-out to @mward-sudo (Michael Ward), who single-handedly ported several modules with complex code. Also thanks to @tenkiller (Brett Fincher), @Sorc96, @Lucassifoni (Lucas Sifoni), @ideaMarcos (Marcos), and @Petarj123 (Petar Jankovic), each of whom contributed multiple ports - and to everyone else who contributed to the porting effort 💜

Here's the breakdown of newly ported functions by module:

Erlang module Functions ported
:binary 13
:elixir_aliases 1
:elixir_locals 1
:elixir_utils 1
:erlang 57
:filelib 1
:filename 10
:init 1
:lists 19
:maps 7
:math 5
:os 3
:rand 1
:re 1
:sets 13
:string 9
:unicode 5
:unicode_util 1
:uri_string 1
Total 150

What This Unlocks

With these ports in place, many more Elixir standard library functions now work in the browser. Here are some examples of what you can use client-side:

  • String processing - String.split/3, String.replace/4, String.length/1, String.jaro_distance/2, and titlecase operations all work in the browser now
  • Collections - Enum and List functions backed by :lists (sorting, filtering, folding, key-based operations on keyword lists) are now available
  • Sets - Full MapSet support via ported :sets functions - create, filter, intersect, union, and check membership
  • Binary & bitstring operations - Pattern matching, splitting, replacing, and searching within binaries
  • Unicode - NFC, NFD, NFKC, and NFKD normalization, plus grapheme cluster segmentation
  • Math - Float.ceil/1, Float.floor/1, power, logarithm, and exponent functions
  • Time - Monotonic time, system time, time unit conversion, and time offsets
  • File paths - Path.join/2, Path.basename/1, Path.dirname/1, Path.extname/1, and more (for client-side path manipulation, not filesystem access)
  • And many, many more - check the Client Runtime Reference for the full picture

Enhancements

Beyond porting, this release brings several improvements that directly affect how you build with Hologram:

  • Faster compilation (#281, thanks @mwmiller) - Compiler mutations are now asynchronous via Agent.cast/2, resulting in measurable compile speed improvement
  • Cross-platform mix setup - Added a setup task for Hologram contributors that works on macOS, Linux, and Windows
  • NixOS compatibility (#639, thanks @ankhers) - Automatic fallback to system-installed Biome when the dynamically-linked Biome dependency binary can't run (common on NixOS, Alpine, and similar systems)
  • More :erlang.float_to_binary/2 options (#371, thanks @ideaMarcos) - :decimals, :compact, and :scientific formatting options are now supported alongside :short
  • Raw HTML blocks in Parser (#287, thanks @mwmiller) - :raw blocks are now emitted from the Parser, enabling more accurate source reconstruction

Bug Fixes

Some of these fixes were already shipped in v0.6.x patch releases:

  • Quota exceeded during page navigation (#272) - Fixed DOMException: The quota has been exceeded by implementing hybrid storage strategy with OPFS
  • Map immutability (#521, thanks @Lucassifoni) - :maps.remove/2 and :maps.put/3 no longer mutate the original map, preserving Erlang's immutability semantics
  • Template interpolation (#276) - Templates now use the String.Chars protocol for interpolation, matching how Elixir string interpolation works, on both client and server
  • Pattern matching with placeholder on right (#642, thanks @prehnRA) - Patterns like :top = _position now work correctly in transpiled code
  • Form events (#260) - Fixed form-level change event detection and submit event form data collection
  • URL parameter encoding - page_path/2 now properly encodes URL parameters, and query params are correctly decoded on navigation, including special character sequences like . and .. that could otherwise trigger path resolution
  • Bitstring segment handling - Fixed placeholder matching and unit resolution in bitstring patterns
  • AST normalization - Fixed handling of try/rescue/catch function ASTs
  • :unicode_util.cp/1 error behavior (#636, thanks @mward-sudo) - Error messages now correctly reference the internal :unicode_util.cpl/2 function, matching Erlang's actual behavior
  • Unported function error message (#640, thanks @prehnRA) - Improved the error message shown when an unported function is encountered; the previous message pointed to a non-existent URL

Infrastructure

Under the hood, this release lays groundwork for upcoming features:

  • Client-side ERTS - New runtime system class with node table, sequence generators, binary pattern registry, and UTF-8 decoder
  • Reference type overhaul - Redesigned internal format and serialization of reference terms to better mirror Erlang behavior
  • ETS infrastructure (#504) - Foundational support for ETS, including state preservation when navigating away from the app
  • Page snapshot improvements - Three-tier storage strategy: in-memory caching for fast access, async OPFS (Origin Private File System) persistence, and session storage as fallback

Upgrading

Update the Hologram dependency in your mix.exs:

{:hologram, "~> 0.7.0"}

Then run:

$ mix deps.update hologram

Thank You

This release would not have been possible without our sponsors and the contributors who joined the porting initiative.

Sponsors

I'd like to thank our sponsors whose support makes sustained development possible:

  • Main Sponsor: Curiosum - ongoing sponsorship along with business insight and adoption guidance, helping shape Hologram's roadmap based on real-world production needs
  • Milestones Sponsor: Erlang Ecosystem Foundation - milestone-based stipend, helping fund key development goals

Thanks also to our GitHub sponsors:

And to all other GitHub sponsors - thank you. Every contribution, no matter the size, helps keep Hologram moving forward.

If you'd like to support Hologram's development, consider sponsoring the project.

Stay in the Loop

Subscribe to the Hologram newsletter for monthly updates on new releases, features, and community news.

What's Next

With 96% of Erlang functions needed for client-side web apps already ported, we're steps away from having a reliable and comprehensive Elixir runtime in the browser. Going forward, expect more granular and more frequent minor releases as we finish the last few pieces of the puzzle and shift focus to polish and stability.

- Bart

联系我们 contact @ memedata.com