Skip to content

feat: add WASM bindings (txm-wasm) - #40

Open
mex7xx wants to merge 3 commits into
thatmagicalcat:mainfrom
mex7xx:feat/wasm-bindings
Open

mex7xx wants to merge 3 commits into
thatmagicalcat:mainfrom
mex7xx:feat/wasm-bindings

Conversation

@mex7xx

@mex7xx mex7xx commented Jul 13, 2026

Copy link
Copy Markdown

What

Adds WebAssembly / JavaScript bindings for TXM, mirroring the existing bindings/py/ pattern. Exposes a single function:

#[wasm_bindgen]
pub fn render(input: &str) -> Result<String, JsValue>

Why

WASM bindings let TXM be used from Node.js, browsers, and any JS runtime — useful for terminal UIs, editors, and tools that want inline LaTeX math rendering without a subprocess.

Files

  • bindings/wasm/src/lib.rs — 7-line wasm_bindgen wrapper around txm::render
  • bindings/wasm/Cargo.toml — standalone [workspace], path-dep on txm with default-features = false (keeps fancy/ratatui out of the wasm build)
  • bindings/wasm/README.md — Node.js build + usage instructions

Design decisions

  • Mirrors bindings/py/ — same standalone-workspace + path-dep pattern, same render -> Result<String, Error> API shape
  • default-features = false — the fancy (yansi) and ratatui features aren't useful in wasm; we only need the plain-text render path
  • No core crate changes — purely additive, can't break existing CLI / PyPI / nix pipelines

Verified locally

$ wasm-pack build bindings/wasm --target nodejs
$ node -e "const {render} = require('./pkg/txm_wasm.js'); console.log(render('\\\\int_0^\\\\infty e^{-x^2}\\\\,dx'))"

∞
⎛   -x²
⎜  e    dx
⎠
0

Suggested CI (couldn't push — fork token lacks workflow scope)

If you'd like CI for the wasm build, here's a ready-to-add .github/workflows/wasm.yml:

name: WASM
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions-rust-lang/setup-rust-toolchain@v1.17.0
        with:
          targets: wasm32-unknown-unknown
      - uses: jetli/wasm-pack-action@v0.4.0
      - run: wasm-pack build bindings/wasm --target nodejs
      - name: Smoke test
        run: |
          node -e "
          const { render } = require('./bindings/wasm/pkg/txm_wasm.js');
          const out = render('E = mc^2');
          if (!out.includes('mc')) { console.error(out); process.exit(1); }
          console.log('OK');
          "

Happy to adjust naming (txm-wasm mirrors txm-py), targets, or structure to match your preferences.

mex7xx added 2 commits July 14, 2026 00:12
Add WebAssembly/JS bindings for TXM, mirroring the existing bindings/py/
pattern. Exposes a single render(input) -> string function via wasm-bindgen.

- bindings/wasm/src/lib.rs: wasm_bindgen wrapper around txm::render
- bindings/wasm/Cargo.toml: standalone workspace, path-dep on txm
- bindings/wasm/README.md: Node.js usage + build instructions
- .gitignore: add pkg/ for wasm-pack output

No changes to the core crate. default-features = false keeps fancy/ratatui
out of the wasm build.
wasm-pack build + node smoke test on push/PR to main.
@thatmagicalcat
thatmagicalcat requested a review from DuskyElf July 13, 2026 22:53
Comment thread .github/workflows/wasm.yml Outdated
node -e "
const { render } = require('./bindings/wasm/pkg');
const out = render('E = mc^2');
if (!out.includes('mc')) { console.error(out); process.exit(1); }

@DuskyElf DuskyElf Jul 14, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why are the tests in the CI and not part of the wasm package ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

sorry, too much vibe coding - agent couldn't access .github/workflows

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a new bindings/wasm/ crate to expose TXM rendering via WebAssembly/JavaScript using wasm-bindgen, following the existing standalone-workspace + path-dependency pattern used by bindings/py/.

Changes:

  • Introduces txm-wasm crate with a single render(&str) -> Result<String, JsValue> export calling into txm::render.
  • Adds Node-focused build and usage documentation for the wasm package.
  • Adds a GitHub Actions workflow to build the wasm bindings and run a minimal Node smoke test.

Reviewed changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
bindings/wasm/src/lib.rs Adds the wasm-bindgen wrapper API over txm::render.
bindings/wasm/README.md Documents building with wasm-pack and Node usage examples.
bindings/wasm/Cargo.toml Defines the txm-wasm crate and its path dependency on txm with default-features = false.
bindings/wasm/Cargo.lock Locks dependencies for the standalone wasm workspace.
.gitignore Ignores wasm-pack build output directory.
.github/workflows/wasm.yml Adds CI build + Node smoke test for wasm bindings.

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

Comment thread .github/workflows/wasm.yml Outdated
Comment on lines +14 to +16
- uses: actions-rust-lang/setup-rust-toolchain@v1.17.0
with:
targets: wasm32-unknown-unknown
Comment thread bindings/wasm/src/lib.rs Outdated
/// Render a LaTeX math expression to Unicode art (one newline-separated row per line).
#[wasm_bindgen]
pub fn render(input: &str) -> Result<String, JsValue> {
libtxm::render(input).map_err(|e| JsValue::from_str(&e.0))
- lib.rs: return JsError instead of JsValue (proper JS Error w/ stack traces)
- lib.rs: add #[test] module (basic, integral, fraction, error cases)
- wasm.yml: fix 'targets:' -> 'target:' (action input key)
- wasm.yml: replace inline node smoke test with 'cargo test'
@mex7xx
mex7xx requested a review from DuskyElf July 14, 2026 23:13
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.

3 participants