Skip to content

Pure-Go bindings via wasm32-wasip1 + wazero (CGO_ENABLED=0) #71

Open

Description

@xusenlin

I've published Go bindings that take a different approach from #30, and
wanted to check whether you'd want them linked from the README, upstreamed,
or simply left downstream.

https://github.com/xusenlin/go-anydoc

#30 binds the crate through cgo with prebuilt per-platform archives. This one
compiles the crate to a wasm32-wasip1 command module, embeds it with
go:embed, and runs it under wazero. The trade-offs are genuinely different,
so I don't think it displaces #30:

  • CGO_ENABLED=0, cross-compiles wherever Go does — verified on
    linux/{amd64,arm64,riscv64,ppc64le,386,s390x}, darwin, windows, freebsd
  • one 4.83 MB wasm artifact instead of a per-platform archive matrix
  • self-contained single binary, no external process, no system deps
  • the cost: interpreted execution. A 1 KB docx converts in 5 ms, but one with
    a 5 MB uncompressed body takes 16.9 s against 1.1 s compiled. There's an
    opt-in WithCompiler() for callers who can afford ~2 s and 576 MB at
    startup.

One thing worth noting given #67: because the crate runs as a sandboxed wasm
guest, the lopdf SIGABRT path surfaces as a returned error rather than
killing the host process — wazero bounds guest call depth and a wasm guest
can't signal the host. A cgo binding has no such containment.

The exit-code table between my WASI shim and the Go error types is pinned to
ConvertError::code(), so I'd like to know how stable you consider that and
to_markdown_bytes to be across releases. The crate is pinned with = and
rebuilds go through a reviewed PR, but I'd rather track your intent than guess.

Happy to move any of this into the repo if a go/ directory using the wasm
path is something you'd want.

Activity

  1. added
    questionFurther information is requested
    P3Low priority or deferred
    on Aug 10, 2026
  2. tomsideguide commented on Aug 10, 2026

    @tomsideguide
    Member

    Go bindings are something we may do in tree later, so I would rather leave this downstream for now than link or upstream it. to_markdown_bytes and ConvertError::code() are stable at the moment, but the crate is pre-1.0 and still moving, so do not treat either as frozen.

  3. xusenlin commented on Aug 10, 2026

    @xusenlin
    Author

    Go bindings are something we may do in tree later, so I would rather leave this downstream for now than link or upstream it. to_markdown_bytes and ConvertError::code() are stable at the moment, but the crate is pre-1.0 and still moving, so do not treat either as frozen.

    Understood, downstream it is. Thanks for the ABI answer — that is the part I
    needed. The bindings pin the crate with =, map unknown code() values onto
    a generic wasm-failure error instead of panicking, and report the embedded
    crate version at runtime, so a pre-1.0 crate that moves degrades rather than
    breaks. I will keep tracking releases manually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low priority or deferredquestionFurther information is requested

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions