Skip to content

High-performance single-binary HTML scripting engine for Go, with .dx files and embedded scripts similar to PHP. Lightweight, concurrent, and easy to deploy anywhere.

License

Notifications You must be signed in to change notification settings

requiem-eco/dirge

Repository files navigation

Dirge Engine

A modern, secure, single-binary alternative to PHP

License Go Version Binary Size

ko-fi

Dirge is a high-performance web engine that combines the simplicity of PHP with modern security and scalability. Write HTML with embedded scripts in .dx files, deploy a single binary, and scale from hobby projects to enterprise applications.

<!-- hello.dx -->
~{ name = "World" }
<h1>Hello, ~{ name }!</h1>
<p>Current time: ~{ GetTime("", TimeNow()) }</p>

πŸš€ Key Features

  • Single Binary - No runtime dependencies, ~50MB
  • Drop-in Templates - .dx files with embedded ~{ } scripts
  • Security First - Auto-escape HTML, sandboxed plugins, prepared statements
  • Blazing Fast - ~14Β΅s per request, optimized for high concurrency
  • Native Minification - HTML/CSS/JS minified in-memory, respects ~{ } scripts
  • Hot-Reload Plugins - Edit Lua plugins without restarting server
  • Event-Driven - WordPress-style hooks and pub/sub events for plugins
  • Enhanced Sandboxing - Resource limits, function restrictions
  • Flexible Deployment - Monolithic, edge-enabled, or multi-region
  • Zero Config - Works out-of-box, customize with TOML

πŸ“š Complete Feature Overview

50+ Built-in Functions
Category Functions
Time GetTime(), GetDate(), GetYear(), GetMonth(), GetDay(), GetHour(), GetMinute(), GetSecond(), TimeNow(), TimeUnix(), TimeUnixNano(), Add(), Subtract(), Diff(), DiffAbs(), FormatUTC()
String Len(), Contains(), Split(), Join(), Trim(), TrimSpace(), ToUpper(), ToLower(), Replace(), HasPrefix(), HasSuffix(), Index(), Substring()
Math Abs(), Min(), Max(), Round(), Floor(), Ceil(), Pow(), Sqrt(), RandomInt(), RandomFloat()
Array ArrLen(), ArrAppend(), ArrContains(), ArrIndex(), ArrReverse(), ArrSlice(), ArrFirst(), ArrLast(), SortStrings(), SortInts()
HTTP HTTPGet(), HTTPPost(), HTTPRequest()
File I/O ReadFile(), WriteFile(), FileExists()
Cache CacheSet(), CacheGet(), CacheDelete(), CacheClear()
Database DBGet(), DBList(), DBCreate(), DBUpdate(), DBDelete(), DBQuery(), DBExec()
Request Query(), Param(), ParamInt(), ParamBool(), Body(), BodyJSON(), BodyRaw(), BodyFile()
Session CreateSession(), GetCurrentUser(), IsAuthenticated(), GetSessionData(), SetSessionData()
Utility If(), GetField(), GetIndex(), escape(), unescape(), Raw(), Sleep(), Env(), Print(), Println(), Sprintf(), TypeOf(), IsNil(), ToString(), ToInt(), ToFloat(), ToBool(), Json(), JsString()
6 Database Drivers
  • SQLite3 - Default, zero-config, perfect for development
  • PostgreSQL - Full SQL support with connection pooling
  • MySQL/MariaDB - Wide compatibility
  • MongoDB - NoSQL document store support
  • CockroachDB - Distributed SQL, geo-replicated
  • YugabyteDB - PostgreSQL-compatible distributed database

Features: Connection pooling, query builder, prepared statements, ORM-like functionality, transactions, migrations (up/down/status/create), schema management, CSV/JSON import, full-text search

Authentication & Security

Auth Types:

  • Session-based (cookie-based for traditional web apps)
  • JWT (stateless APIs, mobile apps)
  • PASETO v4 (modern alternative with v4.public/v4.local variants)
  • OAuth2/OIDC (multiple providers with auto-registration)
  • BasicAuth (admin panel protection)

Key Management:

  • Automatic key rotation (symmetric and Ed25519)
  • gRPC-based key distribution across nodes
  • mTLS for node-to-node communication
  • Clock skew tolerance

Security Features:

  • RBAC registry with custom permission system
  • CSRF protection (token-based)
  • Content Security Policy headers
  • XSS prevention (auto-HTML escaping)
  • Path traversal protection (sandbox enforcement)
  • SQL injection prevention (prepared statements only)
  • Configurable CORS
Caching System

Backends:

  • In-memory (fast, in-process)
  • File cache (persistent, disk-based)
  • Redis/Valkey (distributed, multi-node)
  • Tiered cache (memory + file hybrid)

Features: TTL support, minification caching, function result caching, whitelist/blacklist paths, token caching, ModTime validation

Lua Plugin System
  • Full Lua 5.1 support via GopherLua
  • Hot-reload without server restart
  • Sandboxing with resource limits
  • Inter-plugin communication via events and hooks
  • Plugin registry with lifecycle hooks
  • Full access to database, HTTP client, and cache APIs
Real-time Communication
  • WebSocket hub with broadcasting
  • User channels and room-based routing
  • Optional authentication requirement
  • Message compression
  • Configurable buffer sizes and max message size
  • Presence tracking and typing indicators
Distributed Systems
  • Consul integration for service discovery
  • Redis/Valkey for distributed cache and sessions
  • mTLS encrypted node-to-node communication
  • Automatic failover to secondary nodes
  • Mesh networking with node roles (standalone, master, auth, service, worker, health)
  • Heartbeat protocol with configurable intervals
  • LAN/WAN/satellite latency classes
Observability & Monitoring
  • Structured JSON logging
  • In-memory log buffer (1000 entries)
  • SQL query logging with bind parameters
  • Async error tracking
  • Prometheus metrics export (::Metrics:prometheus)
  • Health checks (::Health:live, ::Health:ready, ::Health:startup)
  • OpenTelemetry distributed tracing (OTLP HTTP)
  • Flight recorder (Go 1.25+)
  • Security audit logging
Static Files & Media
  • Static asset routing with automatic minification
  • Dynamic media routing
  • MIME type handling with cache headers (ETag, Cache-Control)
  • Gzip/Brotli compression middleware
  • Image Processing: libvips integration for resizing, conversion, quality control, metadata stripping
  • File Uploads: Multipart support, configurable storage, filename hashing, date organization, MIME filtering
Cloudflare Integration
  • Real IP detection (CF-Connecting-IP)
  • Country detection (CF-IPCountry)
  • Ray tracing (CF-Ray)
  • Edge caching (s-maxage)
  • Cache tags and purging via API
  • Early hints (103 responses)
  • Auto-updating Cloudflare IP ranges
Additional Features
  • Analytics: Request tracking, performance metrics, referrer/user-agent tracking, device classification, multiple backends (memory/Redis/SQLite)
  • Notifications: Multi-channel delivery (WebSocket, email, webhooks), per-user limits, TTL support
  • Scheduler: Cron-like task scheduling, rate limiting, persistent storage
  • Rate Limiting: IP-based throttling, configurable limits, distributed support via Redis
  • Circuit Breaker: Failure detection, state management, fallback support
  • Moderation: Content filtering, user banning, report system, audit trail
CLI Commands
dirge init <name>           # Create new project scaffold
dirge run                   # Start dev server with live reload
dirge build [--compress]    # Build optimized binary (with UPX option)
dirge migrate up            # Apply pending migrations
dirge migrate down [steps]  # Rollback migrations
dirge migrate status        # Show migration status
dirge migrate create <name> # Create new migration
dirge version               # Show version info
dirge help                  # Show help message

Config flag: -c or --config for custom config file

πŸ’­ Why Dirge?

I got tired of rebuilding, refactoring routes, and recompiling on every change. So I built on Fiber v3 for speed and simplicity.

πŸ“¦ Installation

Binary Release

# Download latest release
wget https://github.com/requiem-eco/dirge/releases/latest/download/dirge-linux-amd64

# Make executable
chmod +x dirge-linux-amd64
mv dirge-linux-amd64 dirge

# Run
./dirge

Build from Source

# Clone repository
git clone https://github.com/requiem-eco/dirge.git
cd dirge

# Build standard binary
make build

# Build edge-optimized binary (smaller, cache-focused)
make edge

# Build for all regions
make edge-all

# Run
./dirge

πŸ“‹ Releases & Versioning

Dirge follows semantic versioning (MAJOR.MINOR.PATCH) with an optimized build strategy:

  • Automated builds on:

    • Every major version (X.0.0)
    • Every 15 minor versions (0.15.0, 0.30.0, etc.)
    • Critical patches (tagged with [critical])
  • Manual builds available for all other versions via source

Latest Release: Check GitHub Releases for binaries

🎯 Quick Start

  1. Create a .dx file in the home/ directory:
<!-- home/hello.dx -->
<!DOCTYPE html>
<html>
<head><title>My First Dirge Page</title></head>
<body>
    ~{ name = "Dirge" }
    <h1>Welcome to ~{ name }!</h1>
    <p>Random number: ~{ RandomInt(1, 100) }</p>
</body>
</html>
  1. Start the server:
./dirge
  1. Visit http://localhost:8080/hello

πŸ“ Syntax Examples

Execution Modes

Synchronous ~{ } - Executes and waits for result (default) Asynchronous ~!{ } - Executes in background, doesn't block render

Variables & Expressions

~{ x = 42 }
~{ name = "Alice" }
<p>x = ~{ x }, x * 2 = ~{ x * 2 }</p>
<p>Hello ~{ ToUpper(name) }!</p>

Functions

<!-- String operations -->
<p>Length: ~{ Len("Hello") }</p>
<p>Upper: ~{ ToUpper("hello") }</p>

<!-- Math operations -->
<p>Random: ~{ RandomInt(1, 100) }</p>
<p>Power: ~{ Pow(2, 10) }</p>

<!-- Time operations -->
<p>Now: ~{ GetTime("", TimeNow()) }</p>
<p>Unix: ~{ TimeUnix() }</p>

Route Parameters

<!-- routes.toml: path = "/user/:id" -->
<h1>User ID: ~{ Param("id") }</h1>
<p>Age: ~{ ParamInt("age") }</p>
<p>Query: ~{ Query("search") }</p>

Async Execution

Execute long-running tasks in background without blocking page render:

<!-- Execute in background with ~!{ } -->
~!{ Sleep(10) }
~!{ CacheSet("background_task", HTTPGet("https://api.example.com/data"), 60) }

<p>Page rendered immediately! Tasks running in background.</p>

Use cases for ~!{ }:

  • API calls that take >1s
  • Cache warming
  • Background data processing
  • Stateful caching operations

πŸ’Ύ Database Support

Dirge supports multiple databases including geo-distributed options:

  • SQLite3 - Default, zero-config, perfect for development
  • PostgreSQL - Production-ready, full-featured
  • MySQL/MariaDB - Wide compatibility
  • MongoDB - NoSQL document store
  • CockroachDB - Geo-distributed SQL, automatic failover
  • YugabyteDB - PostgreSQL-compatible, tunable consistency

Geo-Distributed Setup (CockroachDB)

[database]
type = "cockroachdb"
dsn = "postgresql://dirge@lb:26257/dirge?sslmode=require"

[database.multi_region]
enabled = true
home_region = "us-east-1"
follower_reads = true  # Low-latency reads from local replicas

πŸ”§ Configuration

Create config.toml:

[server]
bind = "0.0.0.0"
port = 8080
root = "./home"
sandbox = true

[http]
tls_enabled = false
allow_cors = true
cors_origins = ["*"]

[limits]
max_request_size = 1048576  # 1MB
max_concurrent_scripts = 100

[cache]
allow_caching = true
cache_memory = true
cache_ttl = 60

πŸ”Œ Lua Plugins

Hot-Reload: Edit plugins without restarting server (when live-reload enabled)

Events & Hooks: WordPress-style filters/actions and pub/sub events

Sandboxed: Resource limits, restricted functions, secure by default

Basic Plugin

-- internals/plugins/api.lua
plugin.register("getUserData", function(ctx)
    local userId = ctx:paramInt("id")
    return ctx:jsonSuccess({
        user = {id = userId, name = "John Doe"}
    })
end, {
    public = true,
    methods = {"GET"}
})

Inter-Plugin Communication

-- Plugin A: Emit events
plugin.register("createUser", function(ctx)
    -- ... create user ...
    plugin.emit("user.register", {user_id = 123})
    return ctx:jsonSuccess({id = 123})
end, {public = true, methods = {"POST"}})

-- Plugin B: Listen to events
plugin.on("user.register", function(event)
    print("New user:", event.data.user_id)
    -- Send welcome email, update analytics, etc.
end)

-- Plugin C: Modify data with filters
plugin.addFilter("user.display_name", 10, function(name, userId)
    if userId == 1 then
        return name .. " [Admin]"
    end
    return name
end)

Map to routes in routes.toml:

[[routes]]
path = "/api/user/:id"
handler = "::getUserData"

πŸ“Š Media & Asset Routing

Serve static files with automatic minification:

# routes.toml
[[media]] # doesn't minify
types = "png,jpg,jpeg,gif"
base_url = "/media"
base_dir = "./media"
dynamic = true

[[assets]]
types = "css,js"
base_url = "/assets"
base_dir = "./assets"
dynamic = false  # Pre-map files on startup

Assets are automatically minified and cached in memory.

πŸ” Admin Routes (Command Server)

Dirge runs two separate HTTP servers:

  • Main Server (port 8080): Public-facing, serves [[routes]]
  • Command Server (port 8081): Admin-only, serves [[admin]] routes

Admin routes are isolated from public traffic for security:

# routes.toml
[[admin]]
path = "/metrics"
handler = "/admin-home/metrics.dx"

[[admin]]
path = "/reload"
handler = "::reloadCache"

Security:

  • Admin routes only accessible on port 8081
  • Bind command server to 127.0.0.1 for localhost-only access
  • Use firewall rules to block external access
  • Add BasicAuth middleware for additional protection

Configuration:

[server]
bind = "0.0.0.0"        # Main server - public
port = 8080
cmd_bind = "127.0.0.1"  # Command server - localhost only
cmd_port = 8081

[auth]
enabled = true
type = "standard"       # Options: "standard", "jwt", "paseto"

πŸ” Authentication & User Systems

Dirge provides flexible authentication primitives instead of rigid RBAC:

Three Auth Modes:

  • Standard: Cookie-based sessions (traditional web apps)
  • PASETO v4: Modern alternative to JWT (better security)
    • v4.public (Ed25519 signing) - Main server only, verifiable by anyone
    • v4.local (symmetric encryption) - Admin server & inter-node communication

Extensibility via Lua Plugins: Build any auth system you need - from simple login to complex RBAC, multi-tenancy, or custom permissions.

-- Example: Custom permission system in Lua
function deleteUser()
    if not hasPermission("users.delete") then
        return {error = "Forbidden"}
    end
    -- Delete user logic
end

register("deleteUser", {public = true, methods = {"DELETE"}})

Available Functions:

  • getCurrentUser() - Get authenticated user
  • hasPermission(perm) - Check custom permission
  • hasRole(role) - Check custom role
  • getSessionData(key) - Retrieve session data
  • Plugin hooks: onLogin, onLogout, onRequest

⚑ Performance

Current Benchmarks (Last tested: 2025-11-24 on AMD Ryzen 7 2700X)

Disclaimer: Tests were performed on AMD Ryzen 7 2700X with a Western Digital Ultrastar DC SN200 NVMe SSD (3,350 MB/s seq read, 835K IOPS random read) in a minimal/base environment. Large-scale production systems with higher loads, multiple services, or resource contention may experience different performance characteristics.

Metric Result
Throughput 66,059 req/sec (2000 concurrent goroutines)
Average Response Time 30.275 ms
99th Percentile 1.204 ms
Fastest Request 141 Β΅s
Slowest Request 552.543 ms
Template Rendering 13.2 Β΅s/req (151x faster than 2ms target)
Route Matching 994 ns/match (2011x faster than 2ms target)
Script Parsing 2.06 Β΅s/parse (972x faster than 2ms target)
Cache Speedup 2.6x faster than disk reads
Binary Size ~50 MB
Memory per Request ~3.2 KB
Error Rate 0% (1,981,567 requests)

Test Suite Status:

  • 87 tests passed, 5 skipped, 0 failed
  • 100% security tests passing (XSS, SQL injection, path traversal prevention)
  • All core modules validated

Optimizations:

  • In-memory HTML/CSS/JS minification
  • File cache with ModTime validation (2.6x faster than disk)
  • Zero-copy static file serving
  • Connection pooling (DB, HTTP)
  • Worker pool (100 goroutines)
  • Minimal allocations per request

Run cd tests/benchmark && go test -bench=. -benchmem to benchmark on your hardware

Deployment Modes:

  • Monolithic: Single instance, local cache/DB (current)
  • Edge-Enabled: Main mesh + lightweight edge gateways (planned)
  • Distributed: Full multi-region with geo-distributed database (future)

πŸ§ͺ Testing

Dirge has a comprehensive test suite covering all modules:

# Run all tests
cd tests && go run main.go --build

# Run specific module
go run main.go server
go run main.go database
go run main.go plugins

# With coverage
go run main.go --coverage

# Performance benchmarks
cd benchmark && go test -bench=. -benchmem

Test Coverage:

  • βœ… Server (routing, middleware, handlers)
  • βœ… Router (path matching, parameters)
  • βœ… Database (query builder, ORM, security)
  • βœ… Plugins (lifecycle, events, hooks, sandbox)
  • βœ… Script engine (parser, renderer, functions, XSS prevention)
  • βœ… Cache system (memory, file, minification, expiration)
  • βœ… Auth system (sessions, security, concurrency)
  • βœ… Security (XSS, SQL injection, path traversal prevention)
  • βœ… Integration (end-to-end scenarios, concurrent requests)

CI/CD Ready:

  • Automated testing on PR/push
  • Performance regression detection
  • Security scanning
  • Cross-platform builds

πŸ›£οΈ Roadmap

Completed:

  • Core .dx execution engine
  • Built-in functions (50+ functions)
  • HTTP client for API requests
  • Scheduler system (cron-like)
  • Lua plugin system with hot-reload
  • Inter-plugin communication (events & hooks)
  • Enhanced sandboxing (resource limits)
  • Native HTML/CSS/JS minifier
  • Media & asset routing
  • Database ORM with query builder
  • Database migrations system (up/down/status/create)
  • Live reload (file watching)
  • Authentication primitives (sessions, JWT, PASETO)
  • Admin panel (command server)
  • Comprehensive test suite
  • CLI tooling (init, run, build, migrate)
  • Auto-update mechanism with GitHub releases
  • Edge binary builds (lightweight gateways)

In Progress:

  • Multi-region support with CockroachDB/YugabyteDB

Planned:

  • Consul service mesh integration
  • Request coalescing & stale-while-revalidate
  • Cross-region write strategies
  • mTLS for edge-to-mesh communication
  • Geo-partitioned data support
  • WebSocket relay for edge nodes
  • Metrics & observability (Prometheus)
  • Plugin marketplace

πŸ“œ License

Dirge Source-Available License 1.0.0

Copyright (c) 2025 SevensRequiem

This software is source-available but NOT open-source. Key restrictions:

  • βœ… View, fork, and modify for personal/educational use
  • βœ… Contribute to official repository
  • ❌ Commercial use without license
  • ❌ Redistribution of binaries
  • ❌ Hosting forks outside official organization

Commercial Licenses: Available for businesses and resellers. Contact: licensing@dirge.one

Future: Automatically converts to MIT License on January 1, 2035 unless updated.

See LICENSE for full terms.

🎯 Target Users

Hobbyists

  • XAMPP-like simplicity
  • Single binary deployment
  • No complex setup

Startups

  • Rapid prototyping
  • Built-in admin panel
  • Easy scaling path

Enterprises

  • High concurrency
  • Horizontal scaling
  • Internal tools

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork within the official organization
  2. Follow existing code style (gofmt)
  3. Add tests for new features (mandatory)
  4. Run test suite before PR: cd tests && go run main.go --build
  5. Update documentation
  6. Ensure all tests pass (no exceptions)

πŸ“ž Support

🌟 Acknowledgments

Built with:


Made with ❀️ by SevensRequiem

why "dirge"? i was thinking of "requiem" related words and remembered this song: Dirge
or maybe it references Naomi Misora..

Can it run on a Floppy Disk?
isTar = true in cnf for grey mode

About

High-performance single-binary HTML scripting engine for Go, with .dx files and embedded scripts similar to PHP. Lightweight, concurrent, and easy to deploy anywhere.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages