CLI
The juice CLI wraps Vite with Juice-specific commands. It is intentionally thin: most commands delegate to Vite with the Juice plugin pre-configured.
juice create <name>
Scaffold a new Juice app. Creates the project directory, installs dependencies, and sets up the file structure.
juice create my-app
juice create my-app --target bun
juice create my-app --target node
juice create my-app --target cloudflare
juice create my-app --target denoValid targets: bun (default), node, cloudflare, deno. The target affects only server.ts (the runtime entry point). Everything else is identical across targets.
Coming from Next.js: equivalent to npx create-next-app. The difference is that Juice asks you where you want to deploy instead of assuming Node.js.
You can also use npx without installing globally:
npx @cmj/juice create my-appjuice dev
Start the Vite dev server with the Juice plugin. Supports all Vite dev flags.
juice dev
juice dev --port 4000
juice dev --host 0.0.0.0The dev server logs each request with method, path, status, and response time:
VITE v6.x.x ready in 150 ms
Routes:
/ home.tsx
/product/:id product/[id].tsx
/api/health api/health.ts
GET / 200 12.3ms
GET /product/42 200 8.1ms
POST /api/contact 303 45.2ms
GET /not-found 404 2.1msThe route table is printed on startup so you can verify which routes were discovered. If a route is missing, check that the file is in app/routes/ and has a default export (for pages) or named HTTP method exports (for API routes).
Server components that throw a Response (redirects, 404s) are logged with the thrown status code, not 200.
juice build
Run the dual Vite build: client build first (produces browser chunks, CSS, and the flight manifest), then SSR build (produces dist/server.js). Supports all Vite build flags.
juice buildOutput structure:
dist/
client/ # Static assets (JS chunks, CSS, images)
assets/
home-a1b2c3.js
global-d4e5f6.css
server.js # Server bundle
flight-manifest.json # Updated manifestWhen to run: before every deployment. If you see stale routes or missing styles in production, run juice build to regenerate everything.
juice preview
Run the production build locally using Vite preview. Serves the built assets and runs the server bundle. Use this to catch production-only issues before deploying.
juice preview
juice preview --port 4000Coming from Next.js: equivalent to next start. The difference is that juice preview uses the same fetch handler as your production deployment.
juice routes
List all discovered routes in the project. Shows URL patterns, file paths, associated layouts, middleware, and HTTP method handlers.
$ juice routes
Route File Layouts Middleware Methods
/ home.tsx layout middleware GET
/about about.tsx layout middleware GET
/product/:id product/[id].tsx layout middleware GET
/blog blog/index.tsx layout middleware GET
/blog/:slug blog/[slug].tsx layout middleware GET
/admin/dashboard admin/dashboard.tsx layout+1 middleware+1 GET
/api/health api/health.ts -- middleware+1 GET
/api/users api/users.ts -- middleware+1 GET, POSTWhen to use: debugging. If a URL returns 404 but you expected it to match a route, run juice routes to see what the compiler discovered.
juice add route <name>
Add a new route file to the project. Creates the file with a default export and response export.
juice add route about # creates app/routes/about.tsx
juice add route blog/[slug] # creates app/routes/blog/[slug].tsx
juice add route api/users # creates app/routes/api/users.ts (no React)Files in api/ directories are created as .ts with HTTP method exports. All others are created as .tsx with a React component.
juice --version
juice --version
juice -vPrints the installed Juice version. Include this in bug reports.
When NOT to Use the CLI
The CLI is a convenience wrapper around Vite. If you have a custom Vite setup (monorepo with shared config, custom plugins), you can use Vite directly with the Juice plugin:
// vite.config.ts
import { defineConfig } from 'vite';
import juice from '@cmj/juice/vite';
export default defineConfig({
plugins: [juice()],
});Then use vite dev, vite build, and vite previewdirectly. The CLI commands are just aliases for these with the Juice plugin pre-loaded.