Migration Guide

Coming from another framework? This guide shows you the Unique.js equivalent of common patterns in Express.js, FastAPI, Actix, Django, Flask, and Spring Boot.

🟢 Express.js

Express.js is the most popular Node.js web framework. Unique.js offers the same simplicity but with 10x better performance and built-in security.

Express.jsUnique.js
const express = require("express")use unique::Unique;
const app = express()let app = Unique::new();
app.get("/path", (req, res) => { ... })app.handle_get("/path", |req, res| { ... })
app.post("/path", (req, res) => { ... })app.handle_post("/path", |req, res| { ... })
res.send("text")res.text("text")
res.json({ key: "value" })res.json(r#"{ "key": "value" }"#)
res.status(404).send("Not Found")res.status(StatusCode::NotFound).text("Not Found")
app.use(express.json())(built-in — no middleware needed)
app.use(cors())(built-in — on by default)
app.use(helmet())(built-in — security headers on by default)
app.use(rateLimit(...))(built-in — 200 burst, 100 rps per IP)
app.listen(3000)app.run("0.0.0.0:3000").await
req.params.idreq.param("id")
req.query.qreq.query("q")
req.bodyreq.body()
req.headers["authorization"]req.header("authorization")

The biggest change is that Unique.js handlers are async closures that return a Response, while Express handlers mutate a Response object. Also, Unique.js does not need body-parser, cors, helmet, or express-rate-limit — they are all built in.

FastAPI (Python)

FastAPI is a modern Python web framework. Unique.js gives you the same developer experience but with 30-50x better performance by running the HTTP engine in Rust.

FastAPI (Python)Unique.js
from fastapi import FastAPIuse unique::Unique;
app = FastAPI()let app = Unique::new();
@app.get("/path")app.handle_get("/path", |req, res| { ... })
@app.post("/path")app.handle_post("/path", |req, res| { ... })
def handler(request: Request):|req: Request, res: Response| { ... }
return {"key": "value"}res.json(r#"{ "key": "value" }"#)
return PlainTextResponse("text")res.text("text")
return HTMLResponse("<h1>Hi</h1>")res.html("<h1>Hi</h1>")
return RedirectResponse("/other")res.redirect("/other")
request.path_params["id"]req.param("id")
request.query_params["q"]req.query("q")
await request.json()req.json::<MyType>()?
uvicorn.run(app, port=3000)app.run("0.0.0.0:3000").await

FastAPI uses Python type hints for validation; Unique.js uses serde for deserialization. FastAPI auto-generates OpenAPI docs from type hints; Unique.js auto-generates them from route metadata. Both approaches require no extra annotations.

🦀 Actix-web (Rust)

Actix-web is a high-performance Rust web framework. Unique.js offers similar performance with a simpler API and polyglot support.

Actix-web (Rust)Unique.js
use actix_web::{App, HttpServer, HttpResponse};use unique::Unique;
HttpServer::new(|| App::new()Unique::new()
.route("/path", web::get().to(handler)) .handle_get("/path", |req, res| { ... })
.route("/path", web::post().to(handler)) .handle_post("/path", |req, res| { ... })
)
.bind("0.0.0.0:3000")?.run("0.0.0.0:3000").await?
.run()
.await
HttpResponse::Ok().body("text")res.text("text")
HttpResponse::Ok().json(data)res.json(serde_json::to_string(&data)?)
HttpResponse::NotFound().finish()res.status(StatusCode::NotFound).text("")
web::Path::<String>::from(req)req.param("id")
web::Query::<T>::from(req)req.query("q")
web::Json::<T>::from(req)req.json::<T>()?

Actix uses extractors (web::Path, web::Query, web::Json) that implement FromRequest. Unique.js puts everything on the Request object directly — simpler API, slightly less type-safe but easier to learn. Actix middleware uses Service trait; Unique.js uses async closures.

🎸 Django (Python)

Django is a batteries-included Python framework. Unique.js provides the same integrated experience (ORM, auth, admin) but in Rust for 50x better performance.

Django (Python)Unique.js
from django.http import HttpResponseuse unique_core::Response;
def view(request):|req, res| { ... }
return HttpResponse("text")res.text("text")
return JsonResponse({"key": "value"})res.json(r#"{ "key": "value" }"#)
urlpatterns = [path("/url", view)]app.handle_get("/url", view)
request.GET.get("q")req.query("q")
request.POST.get("q")req.body() // parse form data
request.headers.get("X-Key")req.header("x-key")
class MyModel(models.Model):#[derive(Model)] struct MyModel {
name = models.CharField(max_length=100) name: String,
MyModel.objects.all()MyModel::all(&db).await?
MyModel.objects.filter(name="x")Query::<MyModel>::select("my_model").where_eq("name", "x").all(&db).await?
MyModel.objects.create(name="x")MyModel { name: "x".into(), .. }.insert(&db).await?
MyModel.objects.get(id=42)MyModel::find_by_pk(42, &db).await?
MyModel.objects.delete(id=42)MyModel::delete_by_pk(42, &db).await?

Django models use class inheritance with metaclass magic; Unique.js uses #[derive(Model)] proc macro. Django ORM is synchronous; Unique.js ORM is async (tokio). Django admin is a full UI; Unique.js generates a basic CRUD dashboard via `unique generate admin`.

🍶 Flask (Python)

Flask is a minimalist Python web framework. Unique.js has the same micro-framework philosophy but with built-in async, security, and 30x performance.

Flask (Python)Unique.js
from flask import Flask, request, jsonifyuse unique::Unique;
app = Flask(__name__)let app = Unique::new();
@app.route("/path")app.handle_get("/path", |req, res| { ... })
@app.route("/path", methods=["POST"])app.handle_post("/path", |req, res| { ... })
return "text"res.text("text")
return jsonify({"key": "value"})res.json(r#"{ "key": "value" }"#)
request.args.get("q")req.query("q")
request.form.get("q")req.body() // parse form data
request.jsonreq.json::<MyType>()?
request.headers.get("X-Key")req.header("x-key")
app.run(port=3000)app.run("0.0.0.0:3000").await

Flask is synchronous; Unique.js is async-first (tokio). Flask needs extensions for everything (Flask-CORS, Flask-Limiter, Flask-SQLAlchemy); Unique.js has all of these built in.

Spring Boot (Java)

Spring Boot is the standard enterprise Java framework. Unique.js provides the same integrated experience with 50x less memory and 10x better throughput.

Spring Boot (Java)Unique.js
@SpringBootApplication// no annotation needed
@RestController// no annotation needed
@GetMapping("/path")app.handle_get("/path", |req, res| { ... })
@PostMapping("/path")app.handle_post("/path", |req, res| { ... })
@RequestMapping(value="/path", method=RequestMethod.PUT)app.handle_put("/path", |req, res| { ... })
public ResponseEntity<String> handler()fn handler(req: Request, res: Response) -> BoxFuture<...>
return ResponseEntity.ok("text")res.text("text")
return ResponseEntity.ok().body(dto)res.json(serde_json::to_string(&dto)?)
@PathVariable String idreq.param("id")
@RequestParam String qreq.query("q")
@RequestBody MyDto dtolet dto: MyDto = req.json()?
@RequestHeader("X-Key") String keyreq.header("x-key")
@Repository / @Entity#[derive(Model)]
JpaRepository<T, Long>impl Model for T { ... } // auto-generated
repository.save(entity)entity.insert(&db).await?
repository.findById(id)Entity::find_by_pk(id, &db).await?
repository.findAll()Entity::all(&db).await?

Spring uses annotations and dependency injection; Unique.js uses closures and explicit function calls. Spring has a steep learning curve (annotations, contexts, beans); Unique.js has a flat learning curve (just closures). Spring uses Hibernate/JPA for ORM; Unique.js has its own proc-macro-based ORM that is simpler but less feature-rich.