From 34% to 96%: The Porting Initiative Delivers - Hologram v0.7.0
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 -
EnumandListfunctions backed by:lists(sorting, filtering, folding, key-based operations on keyword lists) are now available - Sets - Full
MapSetsupport via ported:setsfunctions - 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/2options (#371, thanks @ideaMarcos) -:decimals,:compact, and:scientificformatting options are now supported alongside:short - Raw HTML blocks in Parser (#287, thanks @mwmiller) -
:rawblocks 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 exceededby implementing hybrid storage strategy with OPFS - Map immutability (#521, thanks @Lucassifoni) -
:maps.remove/2and:maps.put/3no longer mutate the original map, preserving Erlang's immutability semantics - Template interpolation (#276) - Templates now use the
String.Charsprotocol 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 = _positionnow 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/2now 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/catchfunction ASTs :unicode_util.cp/1error behavior (#636, thanks @mward-sudo) - Error messages now correctly reference the internal:unicode_util.cpl/2function, 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:
- Innovation Partner: Sheharyar Naseer (@sheharyarn)
- Framework Visionaries: @absowoot, Uzair Aslam (@uzairaslam196), Oban (@oban-bg), Lucas Sifoni (@Lucassifoni), Robert Urbańczyk (@robertu)
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