Kiosk24 (from kušk, Persian for “small pavilion” and “newsstand”) is designed to take hourly (0 * * * *) screenshots of news websites by taking regular screenshots across desktop and mobile device viewports . It allows users to track visual changes over time and compare different versions.
The screenshot agent runs on a Raspberry Pi 5.
I was inspired to build this project by https://youtube.com/watch?v=JTOJsU3FSD8&t=118s
Project Structure
This project is a monorepo:
- apps/agent: A Playwright-based screenshot
- apps/api: A Hono-based backend API running on Cloudflare Workers
- apps/web: An Astro-based frontend
- libs/shared: Shared TypeScript types, Drizzle ORM and zod
%%{init: {
"theme": "base",
"themeVariables": {
"fontFamily": "Inter, Segoe UI, sans-serif",
"primaryColor": "#4F46E5",
"primaryTextColor": "#ffffff",
"primaryBorderColor": "#4338CA",
"lineColor": "#64748B",
"secondaryColor": "#0EA5E9",
"tertiaryColor": "#F1F5F9"
}
}}%%
graph LR
subgraph PI["Raspberry Pi 5"]
Agent["Agent"]
end
subgraph CF["Cloudflare"]
API["API"]
D1[("D1 Database")]
R2[("R2 Storage")]
end
subgraph Browser["Browser"]
Web["Frontend"]
end
Agent ==>|Sends Screenshots| API
API ==>|Provides URLs| Agent
Web ==>|Requests| API
API -->|Stores Metadata| D1
API -->|Stores Images| R2
classDef compute fill:#EEF2FF,stroke:#4338CA,stroke-width:2px,color:#111827;
classDef cloud fill:#E0F2FE,stroke:#0284C7,stroke-width:2px,color:#0C4A6E;
classDef storage fill:#F8FAFC,stroke:#94A3B8,stroke-width:2px,color:#334155;
classDef browser fill:#ECFDF5,stroke:#059669,stroke-width:2px,color:#065F46;
class Agent compute;
class API cloud;
class D1,R2 storage;
class Web browser;
Tech Stack
- Frontend: Astro (Astro joins Cloudflare), Preact, Tailwind CSS
- Security: /dashboard protected with Cloudflare Zero Trust
- Backend: Hono (Cloudflare Workers), Drizzle ORM
- Database: Cloudflare D1
- Storage: Cloudflare R2
- DNS: Cloudflare DNS
- Image Optimization: Cloudflare Image Transformations
- Agent: Playwright, tsup
- Monorepo Management: pnpm
- Linting/Formatting: Biome
Local Development
Prerequisites
- Node.js
- pnpm
1. Clone & Install
git clone https://github.com/herol3oy/kiosk24.git
cd kiosk24
pnpm install2. Generate API Key
3. Setup Environment Variables
agent/.envAPI_BASE_URL=http://localhost:8787 API_KEY=<generated_key>
api/.envCLOUDFLARE_ACCOUNT_ID= CLOUDFLARE_DATABASE_ID= CLOUDFLARE_D1_TOKEN= API_KEY=<generated_key>
web/.envPUBLIC_CDN_URL=http://localhost:8787 API_KEY=<generated_key>
4. Initialize the Database
cd apps/api
npx wrangler d1 migrations apply kiosk24 5. Run the Stack
pnpm --parallel --filter api --filter web run dev
6. Configure & Start Agent
- Go to http://localhost:4321/dashboard
- Add URLs and languages.
- Start the agent:
pnpm --filter agent run dev

