Elixir NIF bindings for Tailwind CSS Oxide — fast parallel content scanning and candidate extraction
  • Elixir 83.4%
  • Rust 16.6%
Find a file
2026-06-11 13:52:41 +03:00
.cargo Add Rustler precompiled NIF support 2026-03-12 09:18:57 +03:00
.github/workflows Use shared Rustler release workflow 2026-06-07 01:30:09 +03:00
lib Update URLs to elixir-volt org 2026-03-12 19:14:14 +03:00
native/oxide_ex_nif Release 0.2.1 2026-05-05 21:53:01 +03:00
test Initial commit — Tailwind CSS Oxide NIF bindings 2026-03-12 09:00:14 +03:00
.credo.exs Initial commit — Tailwind CSS Oxide NIF bindings 2026-03-12 09:00:14 +03:00
.formatter.exs Initial commit — Tailwind CSS Oxide NIF bindings 2026-03-12 09:00:14 +03:00
.gitignore chore: ignore local audit output 2026-06-11 13:52:41 +03:00
Cargo.lock Release 0.2.1 2026-05-05 21:53:01 +03:00
Cargo.toml Initial commit — Tailwind CSS Oxide NIF bindings 2026-03-12 09:00:14 +03:00
checksum-Elixir.Oxide.Native.exs Update precompiled NIF checksums for v0.2.1 2026-05-05 22:14:56 +03:00
LICENSE Initial commit — Tailwind CSS Oxide NIF bindings 2026-03-12 09:00:14 +03:00
mix.exs Use shared Rustler CI workflow 2026-06-07 00:39:30 +03:00
mix.lock Add Rustler precompiled NIF support 2026-03-12 09:18:57 +03:00
README.md README: ecosystem footer linking org and Building Blocks standard 2026-06-11 12:21:41 +03:00

Oxide

Elixir NIF bindings for Tailwind CSS Oxide — the Rust-powered content scanner that powers Tailwind CSS v4.

Scans source files in parallel to extract Tailwind CSS candidate class names at native speed, with built-in support for HEEx, EEx, Elixir, Vue, Svelte, and 20+ other template languages.

Features

  • Parallel filesystem scanning — walks directories using Rayon, respects .gitignore
  • Candidate extraction — state-machine parser pulls valid Tailwind candidates from any content
  • Incremental scanning — only re-extracts changed files, returns only new candidates
  • Language-aware preprocessing — built-in support for .heex, .eex, .ex, .vue, .svelte, .erb, and more
  • Stateless extraction — extract candidates from a string without a scanner

Installation

def deps do
  [
    {:oxide, "~> 0.1.0"}
  ]
end

Requires a Rust toolchain (rustup recommended). The NIF compiles automatically on mix compile.

Usage

Scanner (stateful, incremental)

# Create a scanner with source patterns
scanner = Oxide.new(sources: [
  %{base: "lib/", pattern: "**/*.{ex,heex}"},
  %{base: "assets/", pattern: "**/*.{vue,ts,tsx}"}
])

# Full scan — walks filesystem, returns all candidates
candidates = Oxide.scan(scanner)
# ["flex", "items-center", "bg-blue-500", "hover:text-white", ...]

# On file change — only returns NEW candidates not seen before
new = Oxide.scan_files(scanner, [
  %{file: "lib/app_web/live/page.ex", extension: "ex"}
])
# ["mt-8", "space-y-4"]

# Get discovered files (useful for watcher setup)
files = Oxide.files(scanner)

# Get generated glob patterns
globs = Oxide.globs(scanner)

Extract (stateless)

candidates = Oxide.extract(~s(class="flex bg-red-500 hover:text-white"), "html")
# [
#   %Oxide.Candidate{value: "class", position: 0},
#   %Oxide.Candidate{value: "flex", position: 7},
#   %Oxide.Candidate{value: "bg-red-500", position: 12},
#   %Oxide.Candidate{value: "hover:text-white", position: 23}
# ]

How It Works

This library wraps the tailwindcss-oxide Rust crate — the same scanner used by Tailwind CSS v4 itself. The scanner:

  1. Walks the filesystem in parallel using Rayon, respecting .gitignore rules
  2. Preprocesses each file based on its extension (strips non-class content from HEEx, Vue, etc.)
  3. Runs a state-machine-based extractor that identifies valid Tailwind candidates
  4. Tracks seen candidates for fast incremental scanning on subsequent calls

All NIF calls run on the dirty CPU scheduler so they don't block the BEAM.

Part of Elixir Volt

oxide scans content for Tailwind CSS candidates at native speed, with HEEx/EEx awareness built in.

It is part of a frontend stack that runs inside the BEAM — builds, JS runtimes, icons, and Vue-to-LiveView compilation as supervised parts of the application instead of external toolchain processes. See the Elixir Volt organization for the rest, and Building Blocks for the Future Web for the thesis, architecture, and roadmap that tie them together.

License

MIT — Copyright 2026 Danila Poyarkov