Package Exports
- @cmj/juice/client
- @cmj/juice/create
- @cmj/juice/package.json
- @cmj/juice/plugin
- @cmj/juice/runtime
Readme
🧃 Juice
Zero-bloat React 19 RSC framework.
Streaming SSR. Server Actions. Zero config.
Install
npm install @cmj/juice react@^19 react-dom@^19 vite@^6Quickstart
npx @cmj/create-juice-app my-app
cd my-app
npm install
npm run devOr scaffold for a specific target:
npx @cmj/create-juice-app my-app --target cloudflareTargets: bun (default), node, cloudflare, deno
CLI
| Command | Description |
|---|---|
juice create <name> |
Scaffold a new Juice app |
juice dev |
Start the Vite dev server |
juice build |
Production build (client + SSR) |
API
juice/plugin
The Vite plugin. Zero config.
// vite.config.ts
import { defineConfig } from 'vite';
import juice from '@cmj/juice/plugin';
export default defineConfig({
plugins: [juice()],
});juice/runtime
The WinterCG-compliant edge runtime.
// server.ts
import { createRouter } from '@cmj/juice/runtime';
import manifest from './dist/flight-manifest.json' with { type: 'json' };
const handler = createRouter(manifest);
// handler: (Request) => Promise<Response>Server Actions (Two-Argument Pattern)
Simple form actions receive FormData as the first argument — React 19 native. When you need more power, use ActionContext as the opt-in second argument:
'use server';
import type { ActionContext } from '@cmj/juice/runtime';
// Simple: FormData-only (React 19 native)
export async function addToCart(formData: FormData) {
const id = formData.get('productId');
}
// Power: headers, cookies, params via second arg
export async function processWebhook(body: unknown, ctx: ActionContext) {
ctx.request.headers.get('x-signature');
ctx.cookies.get('session_id');
ctx.params.id;
}Test your actions with the public createActionContext factory:
import { createActionContext } from '@cmj/juice/runtime';
const ctx = createActionContext(new Request('https://example.com'));How It Works
Source (.tsx) → Vite Plugin → flight-manifest.json → Runtime → Response- Compile: The Vite plugin detects
'use client'and'use server'directives, generates proxy modules, and emits aflight-manifest.json. - Serve: The runtime reads the manifest and streams RSC responses using React 19's
renderToReadableStream. - Deploy: The
Request → Responsesignature works on any WinterCG platform.
Client-Side Navigation
import { Link } from '@cmj/juice/client';
<Link href="/about">About</Link>
<Link href="/products" prefetch="viewport">Products</Link>
<Link href="/blog" activeClassName="active">Blog</Link>Programmatic navigation:
'use client';
import { useRouter } from '@cmj/juice/client';
const router = useRouter();
router.push('/dashboard');
router.prefetch('/settings');In dev mode, the Vite plugin auto-injects a client bootstrap that intercepts navigations via the Navigation API — SPA transitions with View Transitions, zero config.
CSS & Styling
Import .css files from any component — they're collected and injected as <link> tags automatically.
// app/routes/layout.tsx
import './global.css';CSS modules work out of the box:
import styles from './Button.module.css';
<button className={styles.root}>Click</button>| Environment | Mechanism |
|---|---|
| Dev | Vite module graph walked recursively — <link> tags in <head> |
| Production | CSS assets tracked in flight-manifest.json under the css key |
PostCSS, Sass, Less, Stylus — anything Vite supports works automatically.
Features
- React 19 RSC — Server Components, Suspense, streaming SSR
- Server Actions —
'use server'with FormData + opt-inActionContextfor headers, cookies, params - SPA navigation —
<Link>component +useRouter()hook + Navigation API bootstrap in dev - CSS pipeline —
import './styles.css', CSS modules, PostCSS, Sass — dev and production - Zero config — One plugin call, no magic files
- One dependency — Only
urlpattern-polyfillfor cross-platform routing - Multi-platform — Bun, Node.js, Cloudflare Workers, Deno
- Empathic errors — "What-Why-How" error messages for fast debugging
- HMR — Full hot module replacement in development
- Testable actions — Public
createActionContextfactory for unit testing
License
MIT