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.fastapi import ArcisMiddleware
from dotenv import load_dotenv
load_dotenv()
app = FastAPI()
app.add_middleware(ArcisMiddleware, block=True)
For custom config, pass keyword arguments to add_middleware:
app.add_middleware(
ArcisMiddleware,
block=True,
sanitize_xss=True,
rate_limit_max=60,
)
Flask (Python)
Flask runs sanitize-only at the middleware layer (block-mode lands in v1.7). For block-mode now, compose scan_threats manually in a before_request handler.
from flask import Flask
from arcis import Arcis
from dotenv import load_dotenv
load_dotenv()
app = Flask(__name__)
Arcis(app)
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.MiddlewareWithConfig(arcisgin.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)
}