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.
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.
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.
Click
The browser runs only the ~2 KB runtime. The island's component code never ships.
WebSocket
The event travels to the Rust server, which holds the connection, presence and heartbeat.
Re-render
The Node renderer re-renders that one island with Preact.
Patch
Rust pushes the resulting HTML patch back down the socket.
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.
// 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>
);
}// 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 directoryroutes/_middleware.tsRuns before routes: auth, redirects, headersroutes/blog/[slug].tsxDynamic route with a server loaderroutes/api/posts.tsGET / POST handlers, streaming Responseroutes/_404.tsx · _500.tsxNot‑found and error pagesislands/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.
| Nowaki | Next.js | Astro | |
|---|---|---|---|
| Server‑reactive islands, zero client JSOnly Nowaki | Jetstream: state on the server, HTML patches over a WebSocket, no component JS | RSC re-renders ship the React runtime | Server Islands defer SSR (one-shot, not live) |
| Toolchain | Rust (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 it | Vite → Rolldown builds it; a JS runtime serves it |
| JavaScript by default | Zero, islands only | Ships React and hydrates | Zero, islands only |
| Full-stack app DX | Routing, loaders, actions, middleware, API, server functions | Yes, mature | Growing, content-first |
| Install without the toolchain's language | npm, no Rust | npm | npm |
| Maturity | Alpha | Mature, huge ecosystem | Mature |
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.
Before 1.0
- State‑preserving (prefresh) HMR
- Scoped CSS for .tsrx islands
- RSC-style streaming boundaries
- A stable public API
Start with one command.
Scaffold
Lays down file-based routes/ and islands/. The CLI is a prebuilt binary, so there is no Rust to install.
Develop
npm run devThe Rust oxc pipeline transforms on demand. Islands hydrate; everything else stays HTML.
Ship
npm run build · startScope-hoisted, content-hashed bundles served in production. Or prerender to static files and put them on a CDN.