Packages
volt
0.1.0
0.17.10
0.17.9
0.17.8
0.17.7
0.17.6
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.12
0.14.11
0.14.10
0.14.9
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
0.13.0
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.9
0.10.8
0.10.7
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.2
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.0
0.1.0
Elixir-native frontend build tool — dev server, HMR, and production builds powered by OXC and Vize.
Current section
Files
Jump to
Current section
Files
README.md
# Volt ⚡
Elixir-native frontend build tool. Dev server with HMR, Tailwind CSS compilation, and production bundling — no Node.js, no esbuild, no Vite.
Built on Rust NIFs: [OXC](https://hex.pm/packages/oxc) for JS/TS, [Vize](https://hex.pm/packages/vize) for Vue SFCs + LightningCSS, [Oxide](https://hex.pm/packages/oxide_ex) for Tailwind scanning, and [QuickBEAM](https://hex.pm/packages/quickbeam) for the Tailwind compiler.
## Features
- **Zero JavaScript toolchain** — no `node_modules`, no npm, no npx
- **JS/TS bundling** — parse, transform, minify via OXC (Rust)
- **Vue SFC support** — single-file components with scoped CSS and Vapor IR
- **Tailwind CSS v4** — parallel content scanning + full compiler, ~40ms builds
- **Dev server** — on-demand compilation with mtime caching and error overlays
- **HMR** — file watcher, WebSocket push, CSS hot-swap without page reload
- **Production builds** — tree-shaken bundles with content-hashed filenames and manifests
## Installation
```elixir
def deps do
[{:volt, "~> 0.1.0"}]
end
```
## Quick Start
### Dev Server
Add the Plug to your Phoenix endpoint:
```elixir
# lib/my_app_web/endpoint.ex
if code_reloading? do
plug Volt.DevServer,
root: "assets",
prefix: "/assets",
target: "es2020"
end
```
Start the watcher in `config/dev.exs`:
```elixir
config :my_app, MyAppWeb.Endpoint,
watchers: [
volt: {Mix.Tasks.Volt.Dev, :run,
[~w(--tailwind --tailwind-css assets/css/app.css --watch-dir lib/)]}
]
```
### Production Build
```bash
mix volt.build \
--entry assets/js/app.ts \
--outdir priv/static/assets \
--resolve-dir deps \
--tailwind --tailwind-css assets/css/app.css
```
```
Building Tailwind CSS...
app.css 23.9 KB
Built Tailwind in 43ms
Building assets/js/app.ts...
app.js 128.4 KB
manifest.json 1 entries
Built in 15ms
```
## Tailwind CSS
Volt compiles Tailwind CSS natively — no CLI binary, no CDN.
[Oxide](https://hex.pm/packages/oxide_ex) scans your source files in parallel for candidate class names, then the Tailwind v4 compiler (running in [QuickBEAM](https://hex.pm/packages/quickbeam)) generates the CSS. [LightningCSS](https://hex.pm/packages/vize) handles minification.
```elixir
# Programmatic API
{:ok, css} = Volt.Tailwind.build(
sources: [
%{base: "lib/", pattern: "**/*.{ex,heex}"},
%{base: "assets/", pattern: "**/*.{vue,ts,tsx}"}
],
css: File.read!("assets/css/app.css"),
minify: true
)
```
Custom CSS works — `@import "tailwindcss"` is inlined automatically:
```css
@import "tailwindcss" source(none);
@custom-variant phx-click-loading (.phx-click-loading&, .phx-click-loading &);
[data-phx-session] { display: contents }
```
### Incremental Rebuilds
In dev mode, only changed files are re-scanned. If a `.heex` template adds new Tailwind classes, only those new candidates trigger a CSS rebuild — the browser gets a style-only update without a page reload.
## HMR
The file watcher monitors your asset and template directories:
| File type | Action |
|-----------|--------|
| `.ts`, `.tsx`, `.js`, `.jsx`, `.vue`, `.css` | Recompile via Pipeline, push update over WebSocket |
| `.ex`, `.heex`, `.eex` | Incremental Tailwind rebuild, CSS hot-swap |
| `.vue` (style-only change) | CSS hot-swap, no page reload |
The browser client auto-reconnects on disconnect and shows compilation errors as an overlay.
## Mix Tasks
### `mix volt.build`
Build production assets.
```
--entry Entry file (default: assets/js/app.ts)
--outdir Output directory (default: priv/static/assets)
--target JS target (default: es2020)
--resolve-dir Additional resolution directory (repeatable, e.g. deps)
--no-minify Skip minification
--no-sourcemap Skip source maps
--no-hash Stable filenames (for dev builds)
--tailwind Build Tailwind CSS
--tailwind-css Custom Tailwind input CSS file
--tailwind-source Source directory for scanning (repeatable)
```
### `mix volt.dev`
Start the file watcher for development.
```
--root Asset source directory (default: assets)
--watch-dir Additional directory to watch (repeatable)
--tailwind Enable Tailwind CSS rebuilds
--tailwind-css Custom Tailwind input CSS file
--target JS target (default: es2020)
```
## Pipeline
`Volt.Pipeline` compiles individual files:
```elixir
# TypeScript
{:ok, result} = Volt.Pipeline.compile("app.ts", source)
result.code #=> "const x = 42;\n"
result.sourcemap #=> "{\"version\":3, ...}"
# Vue SFC
{:ok, result} = Volt.Pipeline.compile("App.vue", source)
result.code #=> compiled JavaScript
result.css #=> scoped CSS (or nil)
result.hashes #=> %{template: "abc...", style: "def...", script: "ghi..."}
# CSS
{:ok, result} = Volt.Pipeline.compile("styles.css", source, minify: true)
```
## Stack
```
volt
├── oxc — JS/TS parse, transform, bundle, minify (Rust NIF)
├── vize — Vue SFC compilation, Vapor IR, LightningCSS (Rust NIF)
├── oxide_ex — Tailwind content scanning, candidate extraction (Rust NIF)
├── quickbeam — Tailwind compiler runtime (QuickJS on BEAM)
└── plug — HTTP dev server
```
## Demo
See [`examples/demo/`](examples/demo/) for a full Phoenix app using Volt + [PhoenixVapor](https://github.com/dannote/phoenix_vapor) — Vue templates rendered as native LiveView, Tailwind CSS, no JavaScript runtime for SSR.
## License
MIT © 2026 Danila Poyarkov