oj
Rust-native Vite-compatible build tool for React apps
TLDR
SYNOPSIS
oj command [root] [options]
DESCRIPTION
oj is a Rust CLI that aims to run existing Vite + React apps without changing their source. It reads `vite.config.{ts,js,mjs}` or `oj.config.*`, adopts `base`, `server.port` / `host`, `define`, and `resolve.alias` when its own config leaves them unset, and runs Vite/Rollup-style plugins through a persistent Node plugin host (`oj.plugins.mjs`, or the `plugins` array in `vite.config`).The compiler is built on Oxc; production linking uses Rolldown. A small Node process is spawned only when plugins, SSR, or server modules need JavaScript. Dev SSR streams HTML with `renderToReadableStream` and hydrates through the normal HMR pipeline.Pointed at a TanStack Start app, oj detects the framework and serves file-based routes with streaming SSR. `oj build` then emits a Node `server.mjs`, a Cloudflare `worker.mjs`, hashed client assets, and prerendered routes.Install from crates.io with `cargo install oj --locked`, or run once with `nix run github:lovablelabs/oj -- dev`.
PARAMETERS
dev [root]
Start the development server. root defaults to the current directory. Default port is 5199.build [root]
Production build. Writes to `dist` unless --outDir is set.preview [root]
Serve a previous production build locally. Default port is 4173.compile file
Compile a single source file to stdout. --prod selects production transforms.--port port
Listen port for dev and preview.--host [host]
Bind address. Bare --host listens on all interfaces.--bundle
(dev) Use bundled registry-runtime mode instead of unbundled ESM.--ssr [entry]
(dev / build) Server-render. In dev, entry is the server module (for example `src/entry-server.tsx`). build --ssr emits a server bundle.-c, --config file
Config file. Otherwise oj.config.* or vite.config.* in the app root is used.-m, --mode mode
Env mode (`development` / `production`). Selects `.env.<mode>` and `import.meta.env.MODE`.--outDir, --out dir
(build / preview) Output directory (default `dist`).--base path
Public base path (default `/`).--emptyOutDir
(build) Empty outDir even when it is outside the project root.--assetsDir dir
(build) Directory under outDir for hashed assets (default `assets`).--assetsInlineLimit bytes
(build) Inline assets smaller than this as data URIs (default 4096).--target target
(build) JS transpile target (default `baseline-widely-available`).--sourcemap [true|false|inline|hidden]
(build) Emit source maps (default off).--minify [minifier]
(build) Minify, or name the minifier (default oxc).--manifest [name]
(build) Write a Vite-style build manifest.--ssrManifest [name]
(build) Write an SSR manifest.--lazy
(dev) Compile modules on demand instead of eagerly crawling the graph on boot.--enable-cache / --no-cache
(dev) Experimental on-disk module cache (also `OJENABLECACHE=1` / `OJNOCACHE=1`). Off by default.--strictPort
(preview) Exit if the port is already in use.--open [path]
(preview) Open a browser on startup.--prod
(compile) Production transforms.
CAVEATS
Experimental: compatibility with the full Vite plugin ecosystem is incomplete. --watch on build is accepted but not implemented. The default dev port is 5199, not Vite's 5173. The `oj` binary name also belongs to online-judge-tools (a competitive-programming CLI); installing both puts one of them first on PATH. A Node runtime is still required for Vite plugins, SSR, and the module runner.
HISTORY
oj was created by Raphael Amorim in 2026 as a Rust-native Vite replacement, then moved to the Lovable GitHub organization (`lovablelabs/oj`). The name is nicknamed "Orange Juice" internally. MIT licensed.
