0.12Release notes

Latest release · [email protected] · alpha

Full-stack like Next.js.Islands like Astro.

Routes, layouts, loaders, actions and API routes, rendered to HTML. Only the islands you mark ship JavaScript, and a Jetstream island ships none: its state stays on the server. The toolchain is Rust (oxc); the dev server is up in under 100 ms.

Quickstart

No Rust needed: the CLI is a prebuilt binary on npm.
Alpha: the API still changes, so don't run production on it yet.

New in this release

Since 0.11

Lazy hydration

Astro-style client:* directives decide when an island hydrates, so islands below the fold cost nothing until they are needed.

Type safety end to end

Typed routes, typed env, and typed client:* directives, checked by your editor before anything runs.

Image optimization in Rust

Image assets are optimized by a pure‑Rust pipeline at build time. No sharp, no native addon to install.

Vercel adapter

Deploy to Vercel through the Build Output API v3, next to the Node, static, Bun, Deno and Cloudflare adapters.

This page ships 14 KB of JavaScript.

The only thing that runs in your browser here is two copy buttons. With Preact, the island runtime and the page router included, that is 14 KB gzipped; the wind and the scroll motion are plain CSS. Built as the same counter app, Nowaki ships about a fifth of Next's JavaScript and has its dev server up in 74 ms.

This site, gzip

This page: copy-button island, runtime, router14 KB
A page with no islands0 KB

Same counter app: first‑load JS, uncompressed

Nowaki21.6 KB
Astro23.1 KB
Next.js app router103.0 KB

Same counter app: dev server ready, cold

Nowaki74 ms
Astro544 ms
Next.js1374 ms

One click, zero component JavaScript.

Mark an island live and its state stays on the server. The browser gets a ~2 KB runtime and HTML patches, never the component's code. Here is one click, end to end.

  1. Click

    The browser runs only the ~2 KB runtime. The island's component code never ships.

  2. WebSocket

    The event travels to the Rust server, which holds the connection, presence and heartbeat.

  3. Re-render

    The Node renderer re-renders that one island with Preact.

  4. Patch

    Rust pushes the resulting HTML patch back down the socket.

  5. Morph

    The runtime morphs the patch into the DOM in place. Client islands keep working beside it.

LiveView's idea, applied per island. RSC re-renders still ship React; Astro's Server Islands render once and don't update. Neither does this.

Write a route. Mark an island. Handle a form.

Routes are components with an optional server-only loader. A non-GET request runs the route's action. Components under islands/ are the only thing that hydrates.

A route with a loaderroutes/blog/[slug].tsx
// routes/blog/[slug].tsx
import Comments from "../../islands/Comments.tsx";

// runs on the server only
export const loader = async ({ params }) => ({
  post: await db.post(params.slug),
});

export default function Post({ data }) {
  return (
    <article>
      <h1>{data.post.title}</h1>
      <Comments postId={data.post.id} /> // only this hydrates
    </article>
  );
}
A form with an actionroutes/guestbook.tsx
// routes/guestbook.tsx
export const loader = (ctx) => ({ entries: read(ctx) });

// a non-GET request runs the action
export async function action(ctx) {
  const form = await ctx.formData();
  ctx.setCookie("guestbook", add(form.get("msg")));
  return ctx.redirect("/guestbook"); // PRG
}

File conventions

routes/_layout.tsxShared layout, nests per directory
routes/_middleware.tsRuns before routes: auth, redirects, headers
routes/blog/[slug].tsxDynamic route with a server loader
routes/api/posts.tsGET / POST handlers, streaming Response
routes/_404.tsx · _500.tsxNot‑found and error pages
islands/Counter.tsxHydrates in the browser. Nothing else does.

Everything else a full‑stack app needs.

Built for dynamic apps in the Next.js and Remix lineage.

Full-stack routing

File-based routes/ with nested _layouts, _middleware, server loaders, form actions, and api/ handlers with method dispatch and streaming.

Server functions

A "use server" module becomes an allowlisted RPC boundary: its code stays on the server, and the client gets a tiny fetch proxy.

Rust toolchain, Node at render time

oxc parses, transforms, bundles and scope-hoists in Rust, with a persistent disk cache. Pages render in a Rust-managed Node sidecar with Preact, so your npm packages keep working.

Island‑to‑island SPA router

Moving between pages with islands is client-side and instant, with prefetch and scroll restoration. Pages with no islands stay zero-JS.

CSS Modules, assets, source maps

*.module.css with scoped class names, hashed imports for images and fonts, and source maps in dev and prod.

Errors you can read

A full-screen overlay with a code frame, hot reload, and live island swap on save.

Next to Next.js and Astro.

None of these ideas is new on its own. Nowaki's bet is the combination. Here is where it differs, and where it doesn't.

FeatureNowakiNext.jsAstro
Server‑reactive islands, zero client JSOnly NowakiJetstream: state on the server, HTML patches over a WebSocket, no component JSRSC re-renders ship the React runtimeServer Islands defer SSR (one-shot, not live)
ToolchainRust (oxc) builds it; in production a Rust server takes requests and sockets and hands rendering to Node (Preact)Turbopack (SWC) builds it; a JS runtime serves itVite → Rolldown builds it; a JS runtime serves it
JavaScript by defaultZero, islands onlyShips React and hydratesZero, islands only
Full-stack app DXRouting, loaders, actions, middleware, API, server functionsYes, matureGrowing, content-first
Install without the toolchain's languagenpm, no Rustnpmnpm
MaturityAlphaMature, huge ecosystemMature

Server functions, streaming SSR, plugins and deploy adapters exist in Next and Astro too, so they are not on this table as differences. Next and Astro are mature and battle-tested; Nowaki is alpha.

Where it fits, and where it stands.

Nowaki fits apps that are mostly content and server data but still dynamic: marketing with auth, docs with interactive widgets, dashboards on real server data, commerce. The kind of page where Next's app-router baseline alone is ~103 KB of JavaScript (uncompressed) before your code.

A good fit

  • You write Next.js‑style apps, but most of each page is static content and server data.
  • You want forms, auth and dynamic routes without paying for a client runtime on every page.
  • You like the Remix‑style loader and action model, with JavaScript shipped only where it is used.

Not yet

  • Fully interactive single‑page apps where almost everything is stateful. Full hydration or RSC fits better there.
  • Production‑critical work today. Nowaki is alpha and the API still moves.

Status: alpha

The core works end to end and is covered by tests in a real browser. The API may still change before 1.0.

Read the full roadmap

Before 1.0

  • State‑preserving (prefresh) HMR
  • Scoped CSS for .tsrx islands
  • RSC-style streaming boundaries
  • A stable public API

Start with one command.

Read the quickstart

Scaffold

Lays down file-based routes/ and islands/. The CLI is a prebuilt binary, so there is no Rust to install.

Develop

npm run dev

The Rust oxc pipeline transforms on demand. Islands hydrate; everything else stays HTML.

Ship

npm run build · start

Scope-hoisted, content-hashed bundles served in production. Or prerender to static files and put them on a CDN.