Skip to content

Introduction

Apion is a lightweight HTTP server framework for Scala.js that provides an Express-like developer experience with the benefits of Scala’s type system, immutability, and pattern matching.

  • Express-like API — Familiar chainable API for JavaScript/Node.js developers
  • Type safety — Compile-time validation with Scala’s type system and zio-json
  • Immutable by design — Pure functions with immutable request/response types
  • Unified handler system — Middleware, routes, and error handlers all share a single type
  • Zero npm dependencies — Pure Scala.js implementation running on Node.js
  • Comprehensive middleware — Authentication, CORS, compression, static files, and more

Every request processor in Apion — whether it’s a route handler, middleware, or error handler — is a Handler:

type Handler = Request => Future[Result]

A handler receives an immutable Request and returns one of four Result types:

ResultMeaning
Continue(request)Pass a (possibly modified) request to the next handler
Complete(response)End the chain and send a response
Fail(error)Propagate a typed error
SkipSkip this handler and try the next one

This unified design means middleware and routes compose naturally — there’s no separate middleware API to learn.

import io.github.edadma.apion._
import zio.json._
case class User(name: String, email: String) derives JsonEncoder, JsonDecoder
@main def run(): Unit =
Server()
.use(LoggingMiddleware())
.use(CorsMiddleware())
.get("/hello", _ => "Hello World!".asText)
.post("/users", _.json[User].flatMap {
case Some(user) => user.asJson(201)
case _ => "Invalid user data".asText(400)
})
.listen(3000) { println("Server running at http://localhost:3000") }
MiddlewarePurpose
AuthMiddlewareJWT authentication with role-based access control
CorsMiddlewareCross-origin resource sharing
SecurityMiddlewareSecurity headers (CSP, HSTS, XSS protection, etc.)
LoggingMiddlewareRequest/response logging (Morgan-style formats)
CompressionMiddlewareResponse compression (Brotli, Gzip, Deflate)
StaticMiddlewareStatic file serving with caching and range requests
CookieMiddlewareCookie parsing, signing, and JSON cookies
RateLimiterMiddlewarePer-IP rate limiting with burst support
FileUploadMiddlewareMultipart file uploads with validation
BodyLimitMiddlewarePer-route request body size limits
  • Scala 3.8.3 with Scala.js 1.21.0
  • zio-json for type-safe JSON encoding/decoding
  • Node.js as the runtime (the only external dependency)
  • Published to Maven Central under io.github.edadma:apion_sjs1_3