Engineering
Updated
3 min read

Arcjet's tech stack

The tech stack behind Arcjet: WebAssembly runtimes, a Go gRPC decision API, and region-aware SNS→SQS→ClickHouse pipeline.

Arcjet's tech stack

Arcjet's SDKs for JavaScript / TypeScript and Python provide developers with the building blocks to create sophisticated security protections in their own code. Developers rely on Arcjet to support high-throughput applications with security decisions returned with very low-latency.

I've talked about how we achieve this from an infrastructure perspective (using AWS's global anycast network), how the decision API is written in Go with a gRPC interface, and that our SDK takes a local-first approach by embedding a WebAssembly module inside the runtime.

In this post, I'll explain the other components of our tech stack and how we build Arcjet at Arcjet.

Arcjet SDKs

The Arcjet SDKs are written in the language they're targeting. For JS/TS this means modern TypeScript (ESM-only). I can't see any reason why you wouldn't be writing a new application in TypeScript today, but we also support JS - it just lacks the type guards that ensure your configuration is valid.

We use standard tooling (Node and NPM) for managing the project to ensure the best compatibility, but run CI with all supported runtimes (Node, Bun, Deno) and frameworks. The SDK has multiple packages - one for each runtime and framework - which are all published to NPM using an automated workflow with humans-in-the-loop for final verification.

For Python, we support asynchronous clients for those building using modern APIs (FastAPI) as well as classic Flask-style synchronous APIs. The repo is managed using uv and the publishing workflow is automated through GitHub Actions to give us build provenance and verification when the package is published to PyPI.

Security decision API

As I've written before, our main backend API is written in Go and uses gRPC as the API protocol format. This is powered by ConnectRPC which gives us a client/server generated from our protobuf definitions that works in JS and Python over HTTP/2 with fallback to HTTP/1.1 and JSON.

Our core rate limiting algorithms are implemented in Lua for Valkey, deployed using AWS ElastiCache. The new remote rules functionality that allows you to dynamically configure Arcjet rules through our web dashboard uses DynamoDB for global replication and low-latency reads.

The WebAssembly module bundled in the SDK is written in Rust. The Go bindings are generated using Gravity and hosted in our Go API using Wazero.

Once requests enter our system and a decision is returned, the request payload is pushed into AWS SNS and distributed into multiple SQS queues for background analysis and recording. We use Clickhouse Cloud for our requests storage backend and analytic. This pipeline is orchestrated using Bento.

Everything runs on AWS EKS with every region isolated and independent. For Fly customers, we also run infrastructure directly on Fly machines.

Web app dashboard

Our core web application where you manage your account, track requests, and configure remote rules, is built in Next.js and React. We self-host on AWS EKS and the backend API (written in Go) connects to Postgres hosted on AWS RDS. Our billing and authentication backends are also written in Go.

Websites

The Arcjet website is built with Next.js and the docs are built with Astro. Both are deployed to Vercel.

Dev tooling

All of our dev environments are within devcontainers and bundle the tooling we use to run the full product locally. Everyone uses Orbstack with Docker Compose. The AWS APIs we use are emulated with Localstack.

All development is container-first: devcontainers + Orbstack + Docker Compose reproduce the full stack locally (including emulated AWS services with Localstack). CI builds are GitHub Actions and production deployments go through Octopus Deploy with human approval.

Devops tooling

All of our code is built using GitHub Actions and then deployed to production using Octopus Deploy.

We use Datadog for external synthetic monitoring and have all our logs, metrics, traces, and dashboards in self-hosted Grafana + Victoria Metrics + Loki + Jaeger. This mostly connects to AWS backed services like OpenSearch. We use PagerDuty for on-call management.

Security

Security is layered: devcontainers reduce local supply-chain exposure, dependency updates are automated with Socket and Renovate, and code is scanned with Semgrep, CodeQL, and Trufflehog. CI is hardened with Harden Runner.

We also use Arcjet itself on our website and app dashboard!

Everything reports into Panther managed by our security team at Latacora.

Related articles

Subscribe by email

Get the full posts by email every week.