Docs/Core Concepts/Rendering Modes
GitHub

Rendering Modes

Nix.js Kit supports four rendering modes. You can mix them in the same app — each route can use a different mode.

# SSG (Static Site Generation)

When: Build time

nix-js-kit build

The kit scans src/app/, runs loaders, composes layout chains, and writes static HTML to dist/.

  • Fastest possible delivery (CDN-cached)
  • No server needed
  • Loaders run once at build time
  • request is undefined in loaders

:::tip SSG is the default and recommended mode for most pages. Use SSR or ISR only for pages that need fresh data. :::

# SSR (Server-Side Rendering)

When: On every request

nix-js-kit start

The SSR server matches the request URL against scanned routes, runs loaders with params, searchParams, and request, then renders the page.

  • Fresh data on every request
  • Access to request (cookies, headers) in loaders
  • Slower than SSG (no CDN cache by default)
  • Combine with ISR for caching
nix-js-kit build          # build the client bundle
nix-js-kit start          # SSR server on http://127.0.0.1:3000

# ISR (Incremental Static Regeneration)

When: Build time + background revalidation

nix-js-kit start --cache-dir .nix-js/cache --default-revalidate 60

ISR combines SSG speed with SSR freshness:

  1. First request renders the page and caches the HTML
  2. Subsequent requests serve the cached HTML (fast)
  3. After revalidate seconds, the next request regenerates the page
  4. The new HTML replaces the cache

Per-page TTL via revalidate export:

// src/app/blog/[slug]/page.data.ts
export const revalidate = 300; // 5 minutes

# Streaming

When: On request (SSR with progressive rendering)

Create a loading.ts file in a route to enable streaming:

// src/app/blog/[slug]/loading.ts
import { html } from "@deijose/nix-js";

export default function BlogLoading() {
  return html`<div class="skeleton">Loading post...</div>`;
}

The server renders the loading shell immediately and the client fetches the real content from /__nix-js/render.

  • Fast initial paint (loading shell)
  • Real content loads asynchronously
  • Works with the SPA router
  • ISR caches the /__nix-js/render endpoint too

:::note Streaming is enabled by default when a loading.ts file exists. You can disable it with streaming: false in createSsrServer. :::

# When to use each

Mode Best for Freshness Speed
SSG Blogs, docs, marketing Build time Fastest
SSR Dashboards, personalized Per request Medium
ISR News, catalogs TTL-based Fast (cached)
Streaming Heavy pages, slow APIs Per request Fast initial paint

# Mixing modes

You can mix modes in the same app:

  • / (home) → SSG
  • /blog/[slug] → ISR with revalidate: 300
  • /dashboard → SSR (needs cookies)
  • /blog/[slug] with loading.ts → Streaming + ISR

The kit automatically detects which mode to use based on:

  • Whether nix-js-kit build or nix-js-kit start is running
  • Whether revalidate is exported
  • Whether loading.ts exists
  • Whether generateStaticParams is exported for dynamic routes
✎ Edit this page on GitHub