Releases: cablehead/http-nu
Release v0.15.0
v0.15.0
Highlights
-
Updated to Nushell 0.112.1 and cross.stream 0.12.0. Nushell removed the
--mergeflag frommetadata set. If you were usingmetadata set --merge {...}, switch to the closure form:metadata set { merge {'http.response': {status: 404}} }. The{ merge {...} }form that was already used in examples and docs continues to work unchanged. -
Security hardening for HTML output. Minijinja templates now autoescape by default. The
.mdcommand escapes code fence language attributes. HTML DSL attribute values are properly escaped. Theescape-htmlutility consistently escapes all five HTML-significant characters (& < > " ') everywhere. -
SSRF fix in reverse proxy. The
strip_prefixlogic now rejects URLs with authority components (e.g.//evil.com) that could confuse downstream routing.
Raw commits
- deps: update nushell to 0.112.1 and cross-stream to 0.12.0 (2026-04-13)
- refactor: unify escape-html to escape all 5 chars everywhere (2026-04-13)
- fix: consolidate HTML escaping, add attribute escaping to HTML DSL (2026-04-13)
- fix: escape code fence language in .md to prevent XSS (2026-04-08)
- fix: enable HTML autoescape in minijinja templates to prevent XSS (2026-04-08)
- fix: prevent SSRF via URL authority confusion in reverse proxy strip_prefix (2026-04-08)
- feat: add cargo-docs example (2026-04-07)
- docs: update v0.14.0 release notes (2026-04-04)
- fix: rename const to avoid collision when sourced from www/serve.nu (2026-04-04)
- fix: use path self for cwd-independent path resolution in templates example (2026-04-03)
- docs: rewrite v0.14.0 release notes (2026-04-04)
- chore: bump to v0.14.1-dev (2026-04-03)
Release v0.14.0
New release, http-nu :: v0.14.0
https://github.com/cablehead/http-nu/releases/tag/v0.14.0
Highlights
.mdsupports GFM: Tables,strikethrough,- [x]checklists, footnotes, and definition lists now render correctly.eval --store <path>:evalnow accepts a--storeflag to use.cat,.append,.casagainst a store directory directly.ICONIFY: Use any of 200k+ icons from Iconify:ICONIFY "lucide:copy",ICONIFY "mdi:home".- Clean SSE shutdown: SSE connections now close immediately on Ctrl+C instead of hanging for 10 seconds.
- Datastar SDK update:
from datastar-signalsnow handles DELETE like GET — signals come from query params, matching the updated ADR. Also addsSCRIPT-DATASTARto emit the client script tag (served from the binary, no CDN needed). - New examples: A blog example showing routing, layouts, and HTML composition, plus a reworked stor example that demonstrates in-memory SQLite by logging its own page views.
href: Mount-aware link helper.$req | href "/about"returns/blog/aboutwhen mounted at/blog.
Release v0.13.0
v0.13.0
Highlights
Updated to Nushell 0.111, cross.stream 0.11, and Datastar v1.0.0-RC.8.
The $HTTP_NU const is now available in handler scripts, providing access to runtime context (version, dev mode, store path, etc.) without environment variables. An examples hub at examples/ showcases available demos with live links.
SSE streams with brotli compression now correctly abort on hot reload, fixing a race where compressed SSE connections could hang during --watch reloads.
The curl hint URL now respects X-Forwarded-Proto when running behind a reverse proxy.
Changelog
- chore: bump Datastar to v1.0.0-RC.8 (2026-03-02)
- feat: add getting started tutorial and unified copy buttons for www site (2026-03-02)
- fix: compose SSE reload-abort with brotli compression (2026-02-26)
- fix: use X-Forwarded-Proto for curl hint URL behind reverse proxy (2026-02-26)
- feat: add curl hint for streaming /time endpoint in basic example (2026-02-26)
- docs: link to live examples from README and examples/README (2026-02-26)
- feat: $HTTP_NU const + examples hub (#42) (2026-02-26)
- examples: add live mermaid editor with Datastar + web component (2026-02-23)
Release v0.12.0
v0.12.0
Highlights
Templates can now load from the store. .mj --topic "page.html" renders a template stored in an xs topic, and {% extends %} / {% include %} references resolve as topic names from the same store. Previously you could load template content via --inline, but if that template referenced other templates they'd resolve from the filesystem -- there was no way for stream-sourced templates to reference each other.
.mj and .mj compile now take exactly one of three mutually exclusive modes:
- File --
{% extends %}/{% include %}resolve from the template's directory on disk - Inline (
--inline) -- self-contained, no resolution - Topic (
--topic, requires--store) -- resolves template names as store topics
examples/templates/ demonstrates all three modes with visually distinct template variants so you can tell which source served the page.
Scripts can use path self for relative paths. Handler scripts no longer need to hardcode paths relative to the working directory:
const script_dir = path self | path dirname
let slides = open ($script_dir | path join data.json)
let page = .mj compile ($script_dir | path join page.html)http-nu eval works the same way, so you can unit test handler endpoints from anywhere:
# test.nu
use std/assert
const script_dir = path self | path dirname
let handler = source ($script_dir | path join serve.nu)
let response = do $handler {method: GET, path: "/", headers: {}}
assert ($response | str contains "<h1>State in the Right Place</h1>")http-nu eval test.nuThe Nushell standard library (std/assert, std/log, etc.) is now available in scripts and eval.
Breaking changes
- feat!: inline mode no longer attaches a filesystem loader --
{% include "local.html" %}in an--inlinetemplate previously resolved from the working directory; use file mode instead
Changelog
- feat!: .mj --topic for store-backed templates (#40) (2026-02-18)
- feat: support path self in file-based scripts (2026-02-18)
- feat: load nushell stdlib into engine (2026-02-19)
- examples: add unit test for tao handler (2026-02-19)
- examples: use path self for relative paths in tao (2026-02-18)
- examples: The Tao of Datastar (#39) (2026-02-18)
- docs: document unit testing endpoints with eval (2026-02-19)
Release v0.11.0
v0.11.0
Highlights
The server can now run entirely from the stream. --topic loads the handler closure from an xs topic instead of a file, and with -w it hot-reloads whenever the topic is updated:
http-nu :3001 --store ./store --topic serve -wIf the topic doesn't exist yet, a placeholder page serves a 503 with instructions on how to get started. Append a closure and the server picks it up:
'{|req| "hello, world"}' | .append serveTopic-sourced handlers get access to VFS modules stored on the stream -- any *.nu topic appended to the store is available via standard use imports, same as with actors and services in xs.
Cookies have first-class support. use http-nu/http gives you cookie parse, cookie set, and cookie delete with secure defaults (HttpOnly, SameSite=Lax, Secure). Multiple cookies accumulate naturally through the pipeline:
use http-nu/http *
{|req|
let cookies = $req | cookie parse
"logged in"
| cookie set "session" "abc123" --max-age 86400
| cookie set "theme" "dark"
}The --dev flag tells the cookie module to omit the Secure attribute, so cookies work over plain HTTP during local development.
Datastar's JS bundle is now embedded in the binary. --datastar serves it at a versioned path with immutable cache headers -- no CDN dependency, zero runtime compression (brotli is pre-built at compile time):
use http-nu/datastar *
SCRIPT {type: "module" src: $DATASTAR_JS_PATH}--expose opens the xs API on an additional address, useful for separating the public-facing HTTP server from the stream management interface. Accepts TCP addresses or iroh:// for peer-to-peer QUIC.
Breaking changes
- feat!: update cross-stream to 0.10.0 -- aligns with the xs processor rename (handlers/generators/commands are now actors/services/actions) and the 2-parameter actor closure shape
Changelog
- feat: add
--topicflag to load handler from xs store - feat: add cookie module (
cookie parse,cookie set,cookie delete) with secure defaults - feat: add
--devflag for development mode - feat: embed Datastar JS bundle, serve via
--datastar - feat: add
--exposeflag to expose xs API on additional address - feat: display startup options and dependency versions in preamble
- feat: VFS modules from the stream available to topic-sourced handlers
- feat: add cross.stream-powered branding
- refactor: bundle handler params into AppConfig struct
- refactor: align with xs processor rename (actor/service/action)
- fix: update actor closure signature to match xs 2-param requirement
- fix: add duration literal support to nushell syntax grammar
Release v0.10.2
v0.10.2
Highlights
- Empty response bodies now default to 204 No Content
- Datastar SDK naming aligned with spec (breaking for datastar users)
- Shutdown message now gets a timestamp like other log lines
- File watcher uses trailing-edge debounce for more reliable reloads
- Bumped cross-stream to 0.9.3
Raw commits
- chore: bump cross-stream to 0.9.3 (2026-01-29)
- feat: timestamp the shutdown message separately from the closing tag (2026-01-29)
- feat: default to 204 No Content for empty response body (2026-01-27)
- refactor(datastar)!: align SDK naming with spec (2026-01-26)
- fix: use trailing-edge debounce for file watcher (2026-01-23)
- docs: update release.md for versioned artifact naming (2026-01-22)
Release v0.10.1
v0.10.1
Highlights
- cargo-binstall support: Install http-nu in seconds with
cargo binstall http-nu - Versioned release artifacts: Release tarballs now include version in filename for better compatibility
Raw commits
- feat: add cargo-binstall support with versioned release artifacts
- docs: update xs command references for 0.9 API
- fix: show usage instead of panic when addr missing
Release v0.10.0
v0.10.0
Highlights
-
.responsereplaced by pipeline metadata (breaking): Usemetadata set --merge {'http.response': {status: 200}}instead -
Content-type inference: Lists become JSON arrays, record streams become JSONL, binary becomes application/octet-stream, empty responses omit the header
-
Nushell 0.110, cross-stream 0.9
-
New commands:
print(logging),to dstar-redirect(Datastar SDK), sqlite commands enabled -
--servicesflag: Enable xs handlers, generators, commands
Changelog
- chore: update to nushell 0.110 and cross-stream 0.9
- feat: lists serialize as JSON arrays, streams as JSONL
- feat: omit Content-Type header for empty responses
- feat: replace .response with pipeline metadata
- feat: abort SSE connections on hot reload
- feat: default binary values to application/octet-stream
- fix: preserve template loader for external refs in .mj commands
- feat: add print command that outputs to logging system
- feat: add SDK test endpoint and support raw string signals
- feat: add to dstar-redirect command for Datastar SDK
- perf: enable LTO and single codegen unit for release builds
- feat: enable sqlite commands in nushell pipelines
- feat: add --services flag to enable xs handlers, generators, commands
Release v0.9.1
v0.9.1
Highlights
.mjnow supports template inheritance and includes ({% extends %},
{% include %},{% import %}). Referenced templates resolve from the
template's directory and subdirectories.
Raw commits
- feat: support template inheritance and includes in .mj (2026-01-10)
- docs: streamline nixos packaging guide (#36) (2026-01-08)
Release v0.9.0
v0.9.0
Highlights
- Breaking: CLI accepts script file directly: The CLI now takes a script file as the main argument. Use
-cfor inline commands. Example:http-nu :3001 ./serve.nuorhttp-nu :3001 -c '{|req| "hello"}' - Watch mode: New
-w/--watchflag enables automatic hot-reload when files change during development - Embedded store: New
--storeflag embeds cross.stream for real-time state and event streaming - Windows Unix socket support: Full Unix socket support on Windows
- Markdown rendering: New
.mdcommand converts Markdown to HTML with syntax-highlighted code blocks - Module paths: New
-I/--include-pathflag for module resolution
Raw commits
- feat: Windows Unix socket support (#35) (2026-01-06)
- test: verify plugin process is shared across requests (2026-01-04)
- feat: embed cross.stream store with --store flag (2026-01-03)
- feat: add -w/--watch flag for file watching and hot reload (2026-01-02)
- feat!: change CLI to accept script file, -c for inline commands (2026-01-02)
- chore: format markdown files (2026-01-02)
- docs: update CSS architecture to prioritize base typography (2026-01-02)
- fix: add base paragraph spacing (2026-01-02)
- docs: document javascript: URL injection vector in .md (2026-01-02)
- feat: add .md command for markdown-to-HTML conversion (2026-01-02)
- docs: add Datastar-ready branding (2026-01-02)
- feat: add --include-path/-I flag for module resolution (2026-01-02)
- feat(www): add Datastar demo, typography system, anchor links (2026-01-02)
- fix: improve error formatting for streaming responses (2026-01-01)
- bench: add Flask+gunicorn comparison benchmark (2026-01-01)
- feat(www): add animated rocket to install section (2026-01-01)
- refactor: replace indicatif with crossterm, add RequestGuard for abort handling (2026-01-01)
- docs(www): add --locked to cargo install, add $ prompts (2026-01-01)