Skip to content

Conversation

@marcoroth
Copy link
Owner

@marcoroth marcoroth commented Aug 27, 2025

This pull request introduces a flexible backend system for the ruby gem, allowing Herb to use different backends.

Currently we implement a native (the previous implementation, based on the Ruby C Extension) and a node backend (that uses the JavaScript packages via nodo). In the future we might want to implement a pure WASM and an FFI backend as well.

This architecture enables the Herb gem to leverage the JavaScript-based tools (formatter, linter, printer) while maintaining the fast native backend for core parsing operations. Users can mix backends for maximum flexibility. So you can parse using the native backend and then format using the node backend.

This pull request introduces a Backend base class with a common interface, similar to how the @herb-tools/core handles this and adds new Herb.format, Herb.lint, and Herb.print_node APIs.

Example usage:

Herb.parse(source)                    # Fast parsing
Herb.parse(source, backend: :native)  # The same as above
Herb.format(source, backend: :node)   # Full formatting features
Herb.lint(source)                     # Auto-selects node backend

Herb.switch_backend(:node)
Herb.parse(source)                    # Now uses node backend

We now also implement a #to_source method on the Node and ParseResult which formats by default:

irb(main):001> puts Herb.parse("<div><div>Hello World</div></div>").to_source
<div>
  <div>Hello World</div>
</div>
=> nil

You can also print the source as it was parsed using the IdentityPrinter by passing (format: false). But this requires the ParseResult to be produced using the Herb.parse(source, track_whitespace: true) option.

irb(main):002> puts Herb.parse("<div><div>Hello World</div></div>").to_source(format: false)
<div><div>Hello World</div></div>
=> nil

@marcoroth marcoroth added feature New feature or request ruby node labels Aug 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request node ruby

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants