@@ -18,10 +18,33 @@ images/audio/METS are rejected with a "rebuild with …" message. Remote
1818` <img src> ` images stay placeholders (no network in the module); embedded
1919images work normally.
2020
21- ** Size: ~ 5.6 MB raw, ~ 1.9 MB gzipped** (measured on this crate at 0.41.x,
22- ` --release ` with the workspace's ` lto = "thin" ` ; no ` wasm-opt ` pass — one
23- typically shaves another 10–15%). No models are involved: the declarative
24- converters and the PDF text parser are pure Rust.
21+ ** Size: ~ 11 MB raw, ~ 3.4 MB gzipped** (measured at 0.49.x — the module now
22+ also carries the browser ML pipeline's pre/post-processing: layout decode, OCR
23+ prep, TableFormer core; ` --release ` with the workspace's ` lto = "thin" ` , no
24+ ` wasm-opt ` pass — one typically shaves another 10–15%). No models are involved
25+ for the declarative converters and the PDF text parser: pure Rust.
26+
27+ ## Install from npm
28+
29+ ``` bash
30+ npm i docling.rs-wasm
31+ ```
32+
33+ ``` js
34+ // Bundlers (Vite, webpack 5 with experiments.asyncWebAssembly):
35+ import { convert } from " docling.rs-wasm" ;
36+
37+ // No bundler (plain <script type="module">): the /web target + explicit init.
38+ import init , { convert } from " docling.rs-wasm/web" ;
39+ await init ();
40+ ```
41+
42+ The package ships both wasm-bindgen targets — ` bundler ` (the default export)
43+ and ` web ` (self-initializing, fetches ` docling_wasm_bg.wasm ` next to the JS).
44+ It is assembled by ` scripts/ci/build_wasm_pkg.sh ` and published by the
45+ ` npm publish ` workflow alongside [ ` docling.rs ` ] ( https://www.npmjs.com/package/docling.rs )
46+ (the native Node bindings — prefer those on servers: full ML pipeline, no wasm
47+ limits).
2548
2649## API
2750
@@ -260,6 +283,64 @@ Resolution order for every model is **device file → local `./models/` →
260283` MODEL_BASE ` (Hugging Face)** . Tables need no upload beyond the model files;
261284the image never leaves the page.
262285
286+ ## Tauri and other desktop shells
287+
288+ Two ways to put docling.rs in a desktop app, and they are not equivalent:
289+
290+ ** Native backend (recommended for Tauri).** A Tauri app's backend * is* Rust,
291+ so skip wasm entirely and depend on the real crates — the webview only renders
292+ the result. This gets the full native pipeline: pdfium rendering, the complete
293+ ML stack (RT-DETR + TableFormer + OCR + enrichment), GPU execution providers,
294+ multi-threading, memory-mapped models — none of which fit the wasm build.
295+
296+ ``` toml
297+ # src-tauri/Cargo.toml
298+ [dependencies ]
299+ docling = { version = " 0.49" } # full default features (ml pipeline)
300+ ```
301+
302+ ``` rust
303+ // src-tauri/src/lib.rs
304+ use docling :: {DocumentConverter , SourceDocument };
305+
306+ #[tauri:: command]
307+ async fn convert_document (path : String ) -> Result <String , String > {
308+ // The ML pipeline is CPU-heavy — keep it off the event loop.
309+ tauri :: async_runtime :: spawn_blocking (move || {
310+ let source = SourceDocument :: from_file (& path ). map_err (| e | e . to_string ())? ;
311+ let result = DocumentConverter :: new ()
312+ . convert (source )
313+ . map_err (| e | e . to_string ())? ;
314+ Ok (result . document. export_to_markdown ())
315+ })
316+ . await
317+ . map_err (| e | e . to_string ())?
318+ }
319+ ```
320+
321+ Ship the ` models/ ` directory as a Tauri resource (or fetch on first run with
322+ ` scripts/install/download_dependencies.sh ` 's URLs) and point the resolver at
323+ it — model paths resolve CWD-relative with env overrides
324+ (` PDFIUM_DYNAMIC_LIB_PATH ` , ` DOCLING_LAYOUT_ONNX ` , …), so set the resource dir
325+ as the working directory or export the variables before the first conversion.
326+
327+ ** Wasm in the webview.** ` docling.rs-wasm ` runs unchanged inside Tauri's (or
328+ Electron's) webview — worth it only when the same SPA must also ship as a
329+ plain web page and you want one code path. The wasm limits apply (declarative
330+ formats + PDF text layer; browser ML needs ONNX Runtime Web + models). One
331+ Tauri-specific note: multi-threaded ONNX Runtime Web needs COOP/COEP headers —
332+ on GitHub Pages the demo fakes them with a service worker (` www/coi.js ` ), but
333+ in Tauri you control the protocol, so serve the app with
334+ ` Cross-Origin-Opener-Policy: same-origin ` and
335+ ` Cross-Origin-Embedder-Policy: require-corp ` directly (e.g. via the
336+ ` app.security.headers ` config or a custom protocol handler) and drop the
337+ service-worker shim.
338+
339+ ** Electron.** Same fork: prefer the native
340+ [ ` docling.rs ` ] ( https://www.npmjs.com/package/docling.rs ) N-API package in the
341+ main process (` ipcMain.handle("convert", …) ` ), keep ` docling.rs-wasm ` for
342+ renderer-only/sandboxed setups.
343+
263344## Performance & threading
264345
265346- ** Threads.** ONNX Runtime Web runs single-threaded unless the page is
0 commit comments