nano-web

command module
v0.5.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 27, 2025 License: MIT Imports: 18 Imported by: 0

README ΒΆ

πŸ”₯ nano-web

publish-container push-package-amd64 Go Report Card

⚑ Hyper-minimal, lightning-fast web server for SPAs and static content

Built on FastHTTP, nano-web is designed for maximum performance and minimal resource usage. Designed for containerized deployments/unikernel environments with immutable content.

✨ What makes nano-web different

  • πŸš„ Ridiculously low latency - Pre-caches everything in memory prec-ompressed with brotli/gzip, serves 100k+ requests/second with sub-millisecond latency.
  • πŸ“¦ Tiny footprint - Tiny (<20MB) Docker image.
  • πŸ”§ Runtime environment injection - Safely inject environment variables at runtime, perfect for easily configuring containers without rebuilding.
  • πŸš‘ Inbuilt Healtchecks - Available at /_health and via the CLI.
  • 🎯 SPA-mode - Supports modern single-page applications with fallback routing.
  • ⚑️ Fast builds - Building an image from nano-web is extremely fast.

πŸ“ˆ Performance

nano-web pre-caches everything in memory with compression, which makes it fast. Benchmark on a M3 Max 36GB:

wrk -d 10 -c 20 -t 10 http://localhost:80
  1,012,393 requests in 10.10s, 7.12GB read
Requests/sec: 100,237
Transfer/sec: 721MB/s
Latency: 200ΞΌs avg (96.93% consistency)

The trade-off is simple: use more memory at startup for faster requests. Your results will vary based on content size and hardware, but the approach is consistent. Generally it shouldn't use that much more RAM than the project.

🐳 Docker

FROM ghcr.io/radiosilence/nano-web:latest
COPY ./dist /public/

Multi-stage builds work great too:

FROM node:18-alpine AS build
WORKDIR /app
COPY . .
RUN npm run build

FROM ghcr.io/radiosilence/nano-web:latest
COPY --from=build /app/dist /public/
ENV SPA_MODE=true
ENV PORT=3000

πŸ”§ Runtime Environment Injection

Instead of rebuilding your app for different environments, inject configuration at runtime:

⚠️ Public config only - don't put secrets here.

<!-- Your index.html -->
<script>
  window.ENV = JSON.parse("{{.EscapedJson}}");
</script>
import { z } from "zod";
// Your React/Vue/whatever app
const ConfigSchema = z.object({
  API_URL: z.string().optional(),
});
const { API_URL } = ConfigSchema.parse(window.ENV));
# Same build, different configs
docker run -e VITE_API_URL=http://localhost:3001 my-app    # dev
docker run -e VITE_API_URL=https://api.prod.com my-app    # prod

βš™οΈ Configuration

Variable CLI Flag Default Description
PORT --port 80 Port to listen on
SPA_MODE --spa-mode false Enable SPA mode (serve index.html for 404s)
CONFIG_PREFIX --config-prefix VITE_ Prefix for runtime environment variable injection
LOG_LEVEL --log-level info Logging level: debug, info, warn, error
LOG_FORMAT --log-format console Log format: json or console
LOG_REQUESTS --log-requests true Enable/disable request logging

πŸš‘ Health checks

Enabled by default at /_health:

{"status":"ok","timestamp":"2025-05-27T08:19:32Z"}

But can also be invoked with nano-web health-check.

πŸ“Ί CLI Usage
Install via Go
go install github.com/radiosilence/nano-web@latest
Download Binary
# Download the latest release for your platform
wget https://github.com/radiosilence/nano-web/releases/latest/download/nano-web-linux-amd64.tar.gz
tar -xzf nano-web-linux-amd64.tar.gz
chmod +x nano-web-linux-amd64

# Or use the shorter name after installation
mv nano-web-linux-amd64 /usr/local/bin/nano-web
Usage Examples
# Basic usage - serve files from ./public/ on port 80
nano-web serve

# Serve files from custom directory on port 8080
nano-web serve ./dist --port 8080

# Enable SPA mode with custom configuration
nano-web serve ./build --port 3000 --spa-mode --log-level debug

# See all available options
nano-web --help
nano-web serve --help

# Health check (useful for monitoring)
nano-web health-check

# Show version
nano-web version

🌰 OPS Microkernels

# Build the unikernel image
ops image create -c config.json --package radiosilence/nano-web:latest -i my-website

# Test locally
ops instance create my-website -c ./config.json --port 8080

# Deploy to cloud
ops instance create my-website -c ./config.json -t gcp

πŸ“Š Logging

Defaults to readable style (--log-format console):

9:15AM INF routes populated successfully route_count=3
9:16AM INF request handled bytes=21 duration=0.044208 method=GET path=/ status=200

Structured JSON for consumption by logging utilities such as DataDog etc (--log-format json) (enabled by default in docker):

# Production (JSON)
{"level":"info","time":"2024-01-15T10:30:45Z","message":"request served","method":"GET","path":"/","status":200,"duration_ms":1.2}

πŸ—οΈ Building from Source

Prerequisites

Install Task for build automation:

# macOS
brew install go-task/tap/go-task

# Linux/Windows - see https://taskfile.dev/installation/
Building
# Clone the repository
git clone https://github.com/radiosilence/nano-web.git
cd nano-web

# See all available tasks
task

# Build for current platform
task build

# Build for all platforms
task build-all

# Run tests
task test

# Run tests with coverage
task test-coverage

# Run benchmarks
task bench

# Development server with hot reload
task dev

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • FastHTTP - The blazing fast HTTP library
  • Zerolog - Structured logging library
  • Brotli - Compression algorithm

Made with πŸ–€ by @radiosilence

Documentation ΒΆ

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL