Framework Adapters
Arcis has built-in adapters for the most popular web frameworks. The core functions are framework-agnostic, so Arcis also works with any framework that isn't listed here.
Jump to a framework
Install in your backend project, not the frontend. All the snippets below are server-side. The .env with ARCIS_KEY goes next to the server entry point. Do not prefix the key with NEXT_PUBLIC_, VITE_, or REACT_APP_. Those bundle into client JS.
Express (Node.js)
The primary Node.js adapter. Works with Express 4 and 5.
import express from 'express';
import { arcis } from '@arcis/node';
import 'dotenv/config';
const app = express();
app.use(express.json());
app.use(arcis({ block: true }));
NestJS (Node.js)
First-party adapter at @arcis/node/nestjs. @nestjs/common is type-only, so non-NestJS users pay nothing.
// app.module.ts
import { Module, MiddlewareConsumer, NestModule } from '@nestjs/common';
import { ArcisModule, ArcisMiddleware } from '@arcis/node/nestjs';
@Module({ imports: [ArcisModule.forRoot({ block: true })] })
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(ArcisMiddleware).forRoutes('*');
}
}
SvelteKit (Node.js)
First-party adapter at @arcis/node/sveltekit. Returns a SvelteKit Handle for src/hooks.server.ts.
// src/hooks.server.ts
import { arcisHandle } from '@arcis/node/sveltekit';
export const handle = arcisHandle({
rateLimit: { max: 100 },
bot: true,
});
// Or compose with other handles via SvelteKit's `sequence` helper:
// import { sequence } from '@sveltejs/kit/hooks';
// export const handle = sequence(arcisHandle(), authHandle);
Astro (Node.js)
First-party adapter at @arcis/node/astro. Returns an Astro MiddlewareHandler for src/middleware.ts.
// src/middleware.ts
import { onRequest as arcisOnRequest } from '@arcis/node/astro';
export const onRequest = arcisOnRequest({
rateLimit: { max: 100 },
bot: true,
});
Nuxt (Node.js, h3)
First-party adapter at @arcis/node/nuxt. Wrap with defineEventHandler in a Nitro server middleware.
// server/middleware/arcis.ts
import { defineEventHandler } from 'h3';
import { arcisHandler } from '@arcis/node/nuxt';
export default defineEventHandler(arcisHandler({
rateLimit: { max: 100 },
}));
Fastify (Node.js)
First-party async plugin at @arcis/node/fastify. Registers onRequest (rate-limit + bot) and onSend (security headers).
import Fastify from 'fastify';
import { arcisFastify } from '@arcis/node/fastify';
const app = Fastify();
await app.register(arcisFastify, { rateLimit: { max: 100 }, bot: true });
Koa (Node.js)
First-party adapter at @arcis/node/koa. (ctx, next) middleware shape: rate-limit + bot before next(); security headers after.
import Koa from 'koa';
import { arcisKoa } from '@arcis/node/koa';
const app = new Koa();
app.use(arcisKoa({ rateLimit: { max: 100 }, bot: true }));
Hono (Node.js, Workers, Deno, Bun)
First-party adapter at @arcis/node/hono. Web Fetch native, type-only hono import — runs on any runtime Hono targets (Cloudflare Workers, Deno Deploy, Bun, AWS Lambda, Node).
import { Hono } from 'hono';
import { arcisHono } from '@arcis/node/hono';
const app = new Hono();
app.use('*', arcisHono({ rateLimit: { max: 100 }, bot: true }));
app.get('/', (c) => c.text('Hello'));
Next.js (Node.js)
First-party adapter at @arcis/node/nextjs. arcisMiddleware is Edge Middleware (Web Fetch native, returns Response | undefined). arcisProtect wraps an App Router route handler with a security-headers post-pass.
// middleware.ts (Edge runtime)
import { arcisMiddleware } from '@arcis/node/nextjs';
export const middleware = arcisMiddleware({
rateLimit: { max: 100 },
bot: true,
});
Bun (Node.js)
First-party adapter at @arcis/node/bun. arcisBun wraps a Bun.serve fetch handler. (For Bun + Hono, use @arcis/node/hono above — it runs on Bun unchanged.)
import { arcisBun } from '@arcis/node/bun';
Bun.serve({
fetch: arcisBun({ rateLimit: { max: 100 }, bot: true }, async (req) => {
return new Response('Hello');
}),
});
FastAPI (Python)
from fastapi import FastAPI
from arcis import ArcisMiddleware
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
app.add_middleware(ArcisMiddleware, block=True)
For custom config:
from arcis import ArcisMiddleware, Config
app.add_middleware(
ArcisMiddleware,
config=Config(
sanitize_xss=True,
rate_limit_max=60,
),
)
Flask (Python)
from flask import Flask
from arcis import Arcis
from dotenv import load_dotenv
load_dotenv()
app = Flask(__name__)
Arcis(app, block=True)
Django (Python)
Add to MIDDLEWARE in settings.py:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'arcis.django.ArcisMiddleware', # add this line
'django.middleware.common.CommonMiddleware',
# ... rest of your middleware
]
Litestar (Python)
First-party adapter at arcis.litestar.ArcisMiddleware. Pure-ASGI middleware, type-only litestar import — composes with Litestar via DefineMiddleware and with any other ASGI host (Starlette, Quart, Hypercorn) via direct instantiation.
from litestar import Litestar
from litestar.middleware.base import DefineMiddleware
from arcis.litestar import ArcisMiddleware
app = Litestar(
middleware=[DefineMiddleware(ArcisMiddleware, block=True)],
)
Gin (Go)
package main
import (
"github.com/gin-gonic/gin"
arcisgin "github.com/GagancM/arcis/gin"
)
func main() {
r := gin.Default()
r.Use(arcisgin.Middleware(arcis.Config{Block: true}))
r.Run()
}
Echo (Go)
package main
import (
"github.com/labstack/echo/v4"
arcisecho "github.com/GagancM/arcis/echo"
)
func main() {
e := echo.New()
e.Use(arcisecho.Middleware())
e.Start(":8080")
}
chi (Go)
First-party adapter at github.com/GagancM/arcis/chi. Granular helpers (Headers / Sanitizer / Validate / Csrf / SecureCookies / Cors / ErrorHandler) plus the bundle middleware. Stdlib-only at runtime — composes with any router accepting func(http.Handler) http.Handler.
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
arcischi "github.com/GagancM/arcis/chi"
)
func main() {
r := chi.NewRouter()
r.Use(arcischi.MiddlewareWithConfig(arcischi.Config{Block: true}))
http.ListenAndServe(":8080", r)
}
Fiber (Go)
First-party adapter at github.com/GagancM/arcis/fiber. Bundle middleware + standalone RateLimit helpers + WithTelemetry option, mirroring the gin/echo/chi shape.
package main
import (
"github.com/gofiber/fiber/v2"
arcisfiber "github.com/GagancM/arcis/fiber"
)
func main() {
app := fiber.New()
cfg := arcisfiber.DefaultConfig()
cfg.Block = true
app.Use(arcisfiber.MiddlewareWithConfig(cfg))
app.Listen(":8080")
}
net/http (Go)
For users without a third-party router, the nethttp subpackage exposes the same middleware shape as a func(http.Handler) http.Handler decorator. Pure stdlib — no chi or fiber dep needed.
package main
import (
"net/http"
archttp "github.com/GagancM/arcis/nethttp"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
})
cfg := archttp.DefaultConfig()
cfg.Block = true
var h http.Handler = mux
h = archttp.MiddlewareWithConfig(cfg)(h)
http.ListenAndServe(":8080", h)
}