From Library to Pipeline: Choosing the Right Surface

The same normalization boundary can be used from very different environments. This chapter focuses on the practical surfaces around anydoc—Rust, Node.js, Python, WebAssembly, the CLI, and the Agent Skill—and on the evidence a team should use before putting one of them in a document pipeline. The goal is not to repeat installation instructions. It is to connect workload constraints to the same detection, model, Markdown, and error contract, then separate project-reported benchmark results from what a particular corpus still needs to prove.

Choose the surface by the constraint you actually have

The Rust crate is the core library. It accepts paths or bytes, can detect a format, can return Markdown, and can stop at the shared document model for model-backed inputs. That surface fits a service or application that wants direct control over the conversion call and its local error handling. It also has the clearest privacy boundary: the Rust core converts locally and does not make network calls for OCR.

Node.js adds a package API and a CLI. The Node binding runs conversion work on the libuv thread pool rather than blocking the event loop, so a JavaScript service can keep its main event loop responsive while a document is processed. The CLI is useful when the surrounding system is a shell pipeline, a batch job, or an agent that needs a command rather than a native library call. It writes Markdown to standard output or a file, reports failures separately, and can request hosted OCR when the input requires it.

Python exposes matching byte and path functions, the shared model, typed conversion exceptions, and the same hosted-OCR option. The binding releases the GIL during conversion, which matters to a threaded Python application that must keep other work moving while a document is parsed. The API choice is therefore about the host runtime’s concurrency and packaging model, not about selecting a different document interpretation.

The browser build uses WebAssembly for local conversion, and the repository also ships an Agent Skill that teaches compatible agents to invoke the CLI. These surfaces change how a document arrives and where the result goes. They do not create a second semantic contract: format detection, the model-backed route, Markdown rendering, and typed failure categories remain the concepts a caller must understand.

A useful selection rule follows. Choose the library binding when the application owns the process and needs model access or structured error handling. Choose the CLI when a process boundary, standard streams, or an agent interface is the natural integration point. Choose browser-local WebAssembly when a browser workflow needs local conversion and the package’s browser constraints fit. Choose a hosted OCR option only when scanned content requires it and the organization accepts the transfer and service dependency. Those are different operating conditions, not a ranking of interfaces.

There is a second selection question after the runtime choice: which representation must remain available. A Markdown-only caller can use the shortest conversion path when text is the final product. A document-model caller may need to retain assets or inspect structure before rendering, but that option is not uniform across accepted formats because PDF has no documented model form. A process that stores only the returned string has also chosen to discard the model-level opportunity.