A fun experiment with Honox (Hono + React), Cloudflare Workers, and KV storage to serve random animal facts (or lies, who knows?).
This project is a playground for testing out modern web technologies:
- Honox: A full-stack framework combining Hono (web framework) with React
- Cloudflare Workers: Edge computing platform for fast, global deployment
- Cloudflare KV: Key-value storage for the facts database
- Rate Limiting: Built-in protection against abuse
The app serves random "facts" about animals (some might be lies, hence the name) through a simple API and displays them in a clean React interface.
- 🚀 Edge-first: Deployed on Cloudflare Workers for global performance
- 🗄️ KV Storage: Facts stored in Cloudflare KV for fast retrieval
- 🛡️ Rate Limited: 10 requests per minute per IP (production only)
- 📱 Responsive: Clean UI built with Tailwind CSS
- ⚡ Fast: Sub-100ms response times at the edge
# Get 1 random fact
GET https://projects.johnnychai.my/the-zoo-of-lies/api
# Get multiple random facts (1-10)
GET https://projects.johnnychai.my/the-zoo-of-lies/api?count=3# Get fact by ID
GET https://projects.johnnychai.my/the-zoo-of-lies/api/2{
"facts": [
{
"id": "30",
"fact": "Hummingbirds are actually tiny helicopters operated by even tinier pilots"
}
],
"count": 1
}- Node.js 18+
- npm or yarn
- Cloudflare account (for deployment)
-
Install dependencies
npm install
-
Start development server
npm run dev open http://localhost:5173/the-zoo-of-lies
This starts the Vite dev server with Hono integration.
-
Preview with Wrangler
npm run preview open http://localhost:8787/the-zoo-of-lies
This runs the app using Wrangler's local development environment.
the-zoo-of-lies/
├── app/
│ ├── components/ # React components
│ ├── islands/ # Honox islands (interactive components)
│ ├── routes/ # Route handlers
│ │ └── the-zoo-of-lies/
│ │ ├── index.tsx # Main page
│ │ └── api/ # API endpoints
│ └── styles/ # Global styles
├── public/ # Static assets
├── wrangler.jsonc # Cloudflare Workers config
└── vite.config.ts # Vite configuration
First, create a KV namespace in your Cloudflare dashboard:
# Create KV namespace
wrangler kv:namespace create "FACTS"
# Create preview namespace for development
wrangler kv:namespace create "FACTS" --previewUpdate the kv_namespaces section in wrangler.jsonc with your namespace IDs.
You'll need to populate your KV store with facts. You can do this through the Cloudflare dashboard or programmatically:
# Add a fact
wrangler kv:key put "1" "Giraffes have the same number of neck vertebrae as humans" --binding FACTS
# Add more facts
wrangler kv:key put "2" "Penguins can jump as high as 6 feet in the air" --binding FACTSThe app uses Cloudflare's rate limiter. Update the unsafe.bindings section in wrangler.jsonc with your rate limiter namespace ID.
# Build and deploy to production
npm run deploy
# Or deploy to a specific environment
wrangler deploy --env prodUpdate the routes section in wrangler.jsonc to use your own domain:
I had mine set as projects.johnnychai.my because I need to had it under a subdomain, but you can use any domain you own.
{
"routes": [
{
"pattern": "yourdomain.com/*",
"zone_name": "yourdomain.com"
}
]
}The app uses these environment variables (configured in wrangler.jsonc):
API_URL: The base URL for API endpointsFACTS: KV namespace binding for facts storageRATE_LIMITER: Rate limiter binding (production only)
- Hono: Fast, lightweight web framework
- Cloudflare Workers: Edge computing platform
- Cloudflare KV: Global key-value storage
- Tailwind CSS: Utility-first CSS framework
- Vite: Build tool and dev server
"This project is hosted on Cloudflare Workers, with KV as the database, because why not make nonsense fast at the edge? Actually, this is just me testing out Hono with React and Cloudflare Workers, playing with their 'cool edge whatever that is.' If you get a laugh (or at least a raised eyebrow), mission accomplished."
MIT License - feel free to use this as a starting point for your own experiments!
