pdf_oxide — Elixir bindings
Idiomatic Elixir bindings for pdf_oxide via a NIF over the C ABI. CPU-bound
extraction runs on dirty CPU schedulers (ERL_NIF_DIRTY_JOB_CPU_BOUND) so
it never blocks the BEAM scheduler. Document/Pdf handles are NIF resources freed
by the GC; functions return {:ok, value} / {:error, code}. Page indices are
0-based.
Install
Published to Hex.pm as pdf_oxide:
# mix.exs
def deps do
[
{:pdf_oxide, "~> 0.3.69"}
]
end
The NIF is built from source on install via elixir_make, linking the
default-feature libpdf_oxide cdylib — see "Build & test" for building it.
Build & test
The NIF links the default-feature cdylib (not the Python wheel):
# 1. build the native library (shipped binding feature set)
cargo build --release --lib --features ocr,rendering,signatures,barcodes,tsa-client,system-fonts
# 2. compile the NIF + test (elixir_make builds c_src/pdf_oxide_nif.c)
cd elixir
mix deps.get
mix compile
LD_LIBRARY_PATH="$PWD/../target/release" mix test
LD_LIBRARY_PATH="$PWD/../target/release" mix run examples/basic_extraction.exs
Use
{:ok, pdf} = PdfOxide.from_markdown("# Hello\n\nbody\n")
{:ok, data} = PdfOxide.to_bytes(pdf)
{:ok, doc} = PdfOxide.open_bytes(data)
{:ok, n} = PdfOxide.page_count(doc)
{:ok, text} = PdfOxide.extract_text(doc, 0)
{:ok, md} = PdfOxide.to_markdown_all(doc)
Layout
elixir/
lib/pdf_oxide.ex idiomatic API (PdfOxide, Document, Pdf, Error)
lib/pdf_oxide/native.ex NIF loader
c_src/pdf_oxide_nif.c dirty-CPU NIF over the C ABI
Makefile builds priv/pdf_oxide_nif.so (via elixir_make)
examples/basic_extraction.exs runnable example (asserted in CI)
test/pdf_oxide_test.exs ExUnit api-coverage (one test per function)
mix.exs
Verification (CI — same set as every binding)
.github/workflows/elixir.yml on Linux + macOS: build cdylib → OTP/Elixir →
mix compile (builds the NIF) → mix test (api-coverage) → run example with an
output assertion.