Skip to content
Open Source Framework

Build with the platform,
not around it.

Juice is a React 19 Server Components framework with 2 dependencies. Your entire server is one function: (Request) => Response. No magic. No lock-in. No abstraction tax.

import { createRouter } from '@cmj/juice/runtime';
import manifest from './flight-manifest.json';

export default { fetch: createRouter(manifest) };

That is the entire server. Four lines. Any runtime.

2
Runtime dependencies
43ms
Cold start (p50)
33.5K
Requests/sec
25KB
Gzipped runtime

Not another Next.js

Juice does not abstract the web platform. It exposes it. Every route is a standard Request in, Response out. Every convention maps to a web standard you already know. When HTTP has a concept for something, Juice uses HTTP. When React has a primitive, Juice uses React. Juice only invents what neither provides.

→

Request in, Response out

No proprietary request objects. No custom response helpers. Standard web APIs from entry point to handler.

â–¡

Manifest bridge

The compiler emits a JSON file. The runtime reads it. No magic module resolution. No framework-specific server hooks. Inspectable, diffable, versionable.

∅

Zero Node.js APIs

The runtime uses Request, Response, ReadableStream, URLPattern. It runs on Cloudflare Workers without polyfills because it was built for Workers, not adapted to them.

What you get

Coming from Next.js?

If you have used Next.js and wished you could just return a Response, or used Remix and wished you had RSC streaming — Juice gives you both without the overhead.

ConceptNext.jsJuice
Route handlerProprietary NextRequestStandard Request/Response
MiddlewareSingle file, edge onlyPer-directory, onion model, everywhere
Data fetchingMagic fetch cachingExplicit cache(fn) dedup
RuntimeNode.js (edge opt-in)WinterCG-first: Workers, Bun, Deno, Node
Server bundle~2MB+ runtime25KB gzipped
StreamingAlways on, limited controlThree modes — you choose

SSR with full hydration

Juice is not just for content sites. Server components render on the server. Client components ('use client') hydrate on the browser with full React interactivity — useState, useEffect, onClick, forms, modals, everything.

â–¶

Server renders first

HTML arrives fully rendered. No blank page, no loading spinner. Search engines see real content immediately.

âš¡

Client hydrates

'use client' components become interactive after hydration. Only client components ship JavaScript to the browser — server components ship zero JS.

↔

SPA navigation

After first load, page transitions fetch RSC payloads and swap content without full reloads. View Transitions API for smooth animations.

Be informed

Juice is early. Here is what you should know before choosing it.

Ecosystem is small

No auth library, no CMS integrations, no community plugins yet. You will build integrations yourself or use platform APIs directly.

Partial rendering is not yet implemented

SPA navigations replace the full React tree. Client state in non-shared components is lost on navigation. Layout preservation is on the roadmap.

You need to understand HTTP

Juice gives you the platform, not abstractions over it. Your team should be comfortable with Request, Response, headers, and status codes.

Start building

npx @cmj/juice create my-app