Show, don't claim
This page ships 12 KB of JavaScript.
Everything interactive on this site, the wind animation, the copy buttons, and the scroll choreography, is 12 KB gzipped with Preact included. A page with no islands ships zero. For comparison, React and ReactDOM alone are about 45 KB gzipped, before any of your own code.
Measured on this site's own production build (it is built with Nowaki). Rigorous head-to-head benchmarks against Next and Astro are on the roadmap.
Speed you feel on every keystroke.
Most JavaScript frameworks boot, transform, and rebuild on a JavaScript toolchain. Nowaki runs that whole pipeline in Rust (oxc), so the dev server is serving before a JavaScript bundler has finished warming up.
Dev server ready, measured on the example app.
To re-transform a changed file with oxc. No JavaScript bundler warm-up.
Production output: modules concatenated into one scope, tree-shaken, content-hashed, with source maps.
From nothing to a running app, without Rust.
npm create nowaki@latestScaffold
Lays down file-based routes/ and islands/. The CLI is a prebuilt binary, so there is no Rust to install.
npm run devDevelop
The Rust oxc pipeline transforms on demand. Islands hydrate; everything else stays HTML. Errors show as a full-screen overlay.
npm run build · startShip
Scope-hoisted, content-hashed ESM and SSR modules, served in production. Or prerender to static and put it on a CDN.
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 loader
// 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 action
// 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 + 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.Honestly, next to Next and Astro.
None of these ideas is new on its own. Nowaki's bet is the combination. Here is where it actually differs, without spin.
| . | Nowaki | Next.js | Astro |
|---|---|---|---|
| Toolchain | Rust (oxc), from scratch | Turbopack (SWC) | Vite → Rolldown |
| JavaScript by default | Zero, islands only | Ships React + hydrates | Zero, islands only |
| Full-stack app DX | Routing, loaders, actions, middleware, API | Yes, mature | Growing, content-first |
| Install without the toolchain's language | npm, no Rust | npm | npm |
| Maturity | Alpha | Mature, huge ecosystem | Mature |
Next and Astro are mature and battle-tested. Nowaki is alpha. The point of the table is the architecture, not a scoreboard.
Who it's for.
Nowaki fits apps that are content-heavy but still dynamic: marketing with auth, docs with interactive widgets, dashboards with real server data, commerce. The kind of page that is mostly text and server data, where a full-hydrate framework still ships a megabyte of JavaScript.
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 full client runtime on every page.
- You like the Remix-style loader and action model, with the parts shipped only where they're used.
Not the sweet spot yet
- Fully interactive single-page apps where almost everything is stateful. Islands fight you there, and full hydration or RSC fits better.
- Production-critical work today: Nowaki is alpha and the API still moves.
A real framework, not a static-site generator.
Built for dynamic apps in the Next.js and Remix lineage, with the parts you actually ship a product on.
Full-stack routing
File-based routes/ with nested _layouts, _middleware, server loaders, actions for forms, and api/ handlers with method dispatch and streaming.
Islands, zero JS by default
Pages render to HTML on the server. Only components under islands/ ship and hydrate, so a page costs only what it actually uses.
Rust toolchain (oxc)
Parse, transform, resolve, bundle, minify, and scope-hoist run in Rust. Fast cold starts, millisecond rebuilds, and a persistent disk cache across restarts.
Installs with npm, no Rust
The CLI ships as prebuilt native binaries through npm's optional dependencies. No cargo, no toolchain, no postinstall.
Island-to-island SPA router
Navigation between island pages is client-side and instant, with prefetch and scroll restoration. Pages with no islands stay zero-JS and navigate normally.
CSS Modules, assets, source maps
*.module.css with scoped class names, hashed imports for images and fonts, and end-to-end source maps in dev and prod.
npm ecosystem, intact
SSR runs on a Rust-managed Node sidecar with Preact, so your existing packages keep working.
Honest dev experience
Full-screen error overlay, code-frame diagnostics, hot reload, and live island swap on save.
Honest about alpha.
Nowaki is young, but the core is real and verified end to end, including in headless Chrome. Here is exactly where it stands.
Works today
- dev / build / start / prerender
- Layouts, middleware, actions, API routes
- Islands + island-to-island SPA router
- CSS Modules, asset imports, source maps
- Scope-hoisted production bundles
- Deploy adapters: Node, static, Bun, Deno, Cloudflare edge
- Streaming SSR + config plugins (transform hooks)
- Rust-free install via npm
On the roadmap
- Jetstream: server-reactive islands (HTML patches over a channel)
- Rust in the production hot path
- State-preserving (prefresh) HMR
- Benchmarks vs Next and Astro