Getting Started
Yang Chun (陽春 — meaning “simple and unadorned”) Comment is a lightweight, privacy-first commenting system built with Lit and Hono, designed to run on Cloudflare Workers. No registration required and no personal data is stored—ideal for small sites and blogs.
✨ Features:
- No login
- No cookies
- No personal data collection
- No browser fingerprinting*
About fingerprinting
Currently we use a hashed IP for backend rate limiting. This provides partial identifiability but is not equivalent to full browser fingerprinting:
- Multiple users on public networks can share the same IP.
- A single user may have different IPs due to ISP dynamic addressing.
An IP cannot uniquely identify a person. In the future we may consider a Proof-of-Work approach to reduce malicious traffic while avoiding hashed IPs.
1. Backend
Section titled “1. Backend”# Clonegit clone https://github.com/ziteh/yangchun-comment.gitcd yangchun-comment
# Install dependencies and buildpnpm installpnpm build
# Move to server foldercd serverCreate a KV namespace (comments data stored here):
pnpm exec wrangler kv namespace create "yangchun-comment-kv"Example response (you’ll get an id to copy):
...
🌀 Creating namespace with title "yangchun-comment-kv"✨ Success!To access your new KV Namespace in your Worker, add the following snippet to your configuration file:[[kv_namespaces]]binding = "yangchun_comment_kv"id = "506ac68ae906458692g22933d3896af3"Update your wrangler.toml and replace the id value with the one returned above:
...
[[kv_namespaces]]binding = "COMMENTS"id = "506ac68ae906458692g22933d3896af3" # Replace with your KV ID
...
# You may modify these values as needed[vars]FRONTEND_URL = "https://your-frontend-url.com" # Frontend URLCORS_ORIGIN = "*" # CORS origin, use "*" to allow all originsRSS_SITE_PATH = "site" # The path for the all-site RSS feedADMIN_USERNAME = "admin" # Admin usernameMAX_MSG_LENGTH = 1000 # The max length of the comment message in charactersMAX_PSEUDONYM_LENGTH = 80 # The max length of the pseudonym in charactersMAX_ALL_SITE_RSS_COMMENTS = 25 # The max number of comments in the all-site RSS feedDeploy to Cloudflare Workers:
pnpm run deployYou should see an endpoint like:
...
Uploaded yangchun-comment-be (3.75 sec)Deployed yangchun-comment-be triggers (0.94 sec) https://yangchun-comment-be.<YOUR_SUBDOMAIN>.workers.devCurrent Version ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxUpdate Secrets. You need to set a security key for HMAC_SECRET_KEY and ADMIN_SECRET_KEY. The value should be a strong random string that is long enough (at least 32 char is recommended). You can use a tool like this, this or this to generate a random key. Also set the admin password ADMIN_PASSWORD.
Use the wrangler secret put to set the secret, which will start the interactive operation and prompt you to enter the value.
# HMAC secret keypnpm exec wrangler secret put "HMAC_SECRET_KEY"
# Admin JWT signature keypnpm exec wrangler secret put "ADMIN_SECRET_KEY"
# Admin login passwordpnpm exec wrangler secret put "ADMIN_PASSWORD"Once completed, you can test it by visiting https://yangchun-comment-be.<YOUR_SUBDOMAIN>.workers.dev/rss/<RSS_SITE_PATH>, which is an RSS feed and will return XML content. Note that the URL does NOT have a trailing slash.
2. Frontend
Section titled “2. Frontend”Install the client package.
pnpm add @ziteh/yangchun-comment-clientnpm i @ziteh/yangchun-comment-clientAdd to your project:
// React example
import { useEffect, useRef } from 'react';import '@ziteh/yangchun-comment-client';import '@ziteh/yangchun-comment-client/style.css';
const API_URL = 'https://yangchun-comment-be.<YOUR_SUBDOMAIN>.workers.dev';
function App() { const wcRef = useRef<HTMLElement | null>(null);
useEffect(() => { if (!wcRef.current) return;
(wcRef.current as any).apiUrl = API_URL; (wcRef.current as any).authorName = 'Test Author'; (wcRef.current as any).post = '/blog/my-post'; }, []);
return ( <div> <yangchun-comment ref={wcRef}></yangchun-comment> </div> );}
export default App;