Integrate SnapAPI into Hono applications running on Cloudflare Workers, Deno, Bun, and Node.js with middleware, validation, caching, and streaming PDF responses.
Hono is the fastest edge-compatible HTTP framework available in 2026, designed from the ground up to run on Cloudflare Workers, Deno, Bun, AWS Lambda, and Node.js with a single, unified API. Its ultra-small bundle size (under 14KB), zero-dependency core, and Web Standards-based API make it the go-to choice for building screenshot proxy services that need to run at the network edge with minimal cold start latency. Hono's middleware system, built-in validator, and JSX support round out a framework that covers every layer of a production screenshot service without requiring additional dependencies.
This guide covers building a complete Hono screenshot service including route definition with TypeScript, Zod request validation via the Hono Zod validator middleware, bearer token authentication, KV-based caching on Cloudflare Workers, and streaming PDF response handling.
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
type Bindings = { SNAPAPI_KEY: string; CACHE: KVNamespace }
const app = new Hono<{ Bindings: Bindings }>()
const schema = z.object({
url: z.string().url(),
width: z.number().min(320).max(2560).default(1280),
height: z.number().min(200).default(800),
format: z.enum(['png', 'jpeg', 'pdf']).default('png'),
full_page: z.boolean().default(false),
})
app.post('/screenshot', zValidator('json', schema), async (c) => {
const body = c.req.valid('json')
const res = await fetch('https://api.snapapi.pics/v1/screenshot', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': c.env.SNAPAPI_KEY,
},
body: JSON.stringify(body),
})
if (!res.ok) return c.json({ error: 'Screenshot failed' }, res.status as any)
return c.json(await res.json())
})
export default app
Protect your screenshot endpoint with bearer token authentication using Hono's built-in auth middleware:
import { bearerAuth } from 'hono/bearer-auth'
app.use('/screenshot', bearerAuth({ token: (c) => c.env.SERVICE_TOKEN }))
Cache screenshot results in Cloudflare KV to minimize redundant SnapAPI calls and reduce latency for frequently requested screenshots:
import { createHash } from 'node:crypto'
app.post('/screenshot/cached', zValidator('json', schema), async (c) => {
const body = c.req.valid('json')
const key = createHash('md5').update(JSON.stringify(body)).digest('hex')
const cached = await c.env.CACHE.get(key, 'json')
if (cached) return c.json(cached)
const res = await fetch('https://api.snapapi.pics/v1/screenshot', {
method: 'POST',
headers: { 'X-API-Key': c.env.SNAPAPI_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(body),
})
if (!res.ok) return c.json({ error: 'Screenshot failed' }, res.status as any)
const data = await res.json()
await c.env.CACHE.put(key, JSON.stringify(data), { expirationTtl: 3600 })
return c.json(data)
})
Stream PDF bytes directly to the client without buffering in memory:
app.post('/pdf', async (c) => {
const { url } = await c.req.json()
const upstream = await fetch('https://api.snapapi.pics/v1/screenshot', {
method: 'POST',
headers: { 'X-API-Key': c.env.SNAPAPI_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ url, format: 'pdf', full_page: true }),
})
return new Response(upstream.body, {
headers: {
'Content-Type': 'application/pdf',
'Content-Disposition': 'attachment; filename=screenshot.pdf',
},
})
})
Add IP-based rate limiting using Hono middleware to prevent quota exhaustion from aggressive clients:
app.use('/screenshot/*', async (c, next) => {
const ip = c.req.header('CF-Connecting-IP') || 'unknown'
const key = `ratelimit:${ip}`
const count = parseInt(await c.env.CACHE.get(key) || '0')
if (count >= 10) return c.json({ error: 'Rate limited' }, 429)
await c.env.CACHE.put(key, String(count + 1), { expirationTtl: 60 })
return next()
})
Deploy your Hono screenshot service to Cloudflare Workers with wrangler deploy. Configure KV namespace bindings in wrangler.toml, set SNAPAPI_KEY as a Cloudflare secret with wrangler secret put SNAPAPI_KEY, and your screenshot service is live globally on Cloudflare's edge network in under 30 seconds. Hono's Cloudflare Workers adapter is production-hardened and requires zero compatibility flags or special runtime configuration — it works out of the box with the current Workers runtime. For local development, wrangler dev provides a local simulation of the Cloudflare Workers environment including KV namespace access. Sign up at snapapi.pics to get your free API key and deploy your first Hono screenshot service today.
Cloudflare Workers has become the deployment target of choice for latency-sensitive API services. Its global edge network means your code runs within milliseconds of your users regardless of whether they are in Tokyo, Frankfurt, or Sao Paulo. Hono is the framework that makes building on Workers feel natural: it provides an Express-like routing API, first-class TypeScript support, and zero-dependency middleware that compiles to tight Worker bundles. When you combine Hono with SnapAPI as your screenshot backend, you get a globally distributed screenshot proxy with caching, authentication, and rate limiting baked in from the start.
There are several good reasons to place a Hono Worker between your application and the SnapAPI endpoint. First, you can add your own authentication layer so that your SnapAPI key never touches client-side code. Your Worker validates a bearer token issued by your auth system, then forwards the request to SnapAPI using the secret key stored in a Cloudflare Worker secret. Second, you can apply response caching using Cloudflare KV or the Cache API. If ten users request a screenshot of the same URL within a short window, your Worker serves the cached image for nine of those requests and only bills one SnapAPI call. Third, you can enforce business-logic-level rate limits that go beyond what SnapAPI's own limits enforce, preventing any single tenant in a multi-tenant application from exhausting your quota.
Cloudflare KV is a globally replicated key-value store with strong read performance and eventual write consistency. For screenshot caching, the natural cache key is a hash of the target URL combined with the screenshot parameters. When a request arrives, your Hono handler computes this hash, checks KV for a cached value, and returns it immediately if present. Cache misses trigger a SnapAPI call, and the response is written back to KV with a TTL that matches your freshness requirements. For marketing pages that change infrequently, a 24-hour TTL is reasonable. For dashboards that update every few minutes, a 60-second TTL prevents stale images without significantly increasing SnapAPI usage. The KV write is done asynchronously using the Workers execution context's waitUntil method so that it does not add latency to the response path.
Accepting arbitrary URLs from clients is a security risk. Without validation, a malicious user could pass internal network addresses, localhost URLs, or redirect chains designed to probe your infrastructure. Zod lets you define a schema that enforces a whitelist of allowed protocols, a maximum URL length, and optional domain allowlisting. The Hono validator middleware integrates directly with Zod schemas, rejecting non-conforming requests with a structured 400 response before any screenshot work begins. This keeps your SnapAPI usage clean and your billing predictable while protecting against server-side request forgery attacks.
When your Hono Worker proxies a SnapAPI PDF request, you have two options: buffer the entire PDF in Worker memory before returning it, or stream the response directly to the client. Streaming is almost always preferable. Cloudflare Workers have a 128 MB memory limit per invocation, and large full-page PDFs can easily approach tens of megabytes. By passing the SnapAPI response body directly to the Hono response without buffering, you keep memory usage low and time-to-first-byte fast. The client's browser begins receiving PDF data before SnapAPI has finished generating it, which is especially noticeable on slow connections. Implementing this in Hono requires returning a Response object constructed from the SnapAPI fetch response's body stream, with the appropriate Content-Type and Content-Disposition headers forwarded from SnapAPI's response.
Wrangler is the official Cloudflare Workers CLI. After defining your KV namespace bindings and secrets in wrangler.toml, a single wrangler deploy command pushes your Hono Worker to all Cloudflare edge locations simultaneously. There is no Docker image to build, no Kubernetes manifest to apply, and no region selection to configure. Your screenshot proxy is live globally within seconds of the deploy command completing. Wrangler also supports environment-specific configurations, so you can maintain separate development and production SnapAPI keys and KV namespaces without any code changes between environments.
Wrangler's development server runs your Worker code locally using the same V8 isolate runtime as production Cloudflare Workers. You can test your Hono screenshot proxy against live SnapAPI endpoints before deploying, verify that your Zod validation correctly rejects malformed requests, and confirm that KV bindings resolve properly using Wrangler's local KV simulation. This tight local feedback loop accelerates development significantly compared to deploying to a staging environment for every change.