A lightweight note-taking app built with TypeScript, deployed on Cloudflare Workers, and stored in R2.
- simple editor with autosave
- shareable note URLs
- 5-character note IDs
- curl-friendly read/write behavior
- delete note by clearing content
- print support
- responsive UI
- single Worker deployment on
workers.dev
- Cloudflare Workers
- TypeScript
- R2
- vanilla HTML/CSS/JS
- Vitest
- Wrangler
.
├── src/
│ ├── index.ts
│ ├── html.ts
│ ├── note.ts
│ ├── response.ts
│ ├── storage.ts
│ └── types.ts
├── test/
│ ├── index.test.ts
│ └── note.test.ts
├── .github/workflows/
│ ├── test.yml
│ └── deploy-worker.yml
├── DEPLOY.md
├── package.json
├── tsconfig.json
└── wrangler.toml
- Node.js 22+
- npm
- Cloudflare account
- R2 bucket(s)
npm ci
npm run verify
npm run devnpm run dev
npm run test
npm run typecheck
npm run deploy:dry-run
npm run verify
npm run deployGET /— open a blank noteGET /noteid/:id— open an existing notePOST /— create a new notePOST /noteid/:id— update or delete an existing noteGET /favicon.ico— favicon
JSON request body:
{
"noteId": "ABCDE",
"content": "hello"
}Rules:
- note IDs are alphanumeric
- generated note IDs are 5 characters
- max note size is 256 KB
- empty content deletes the note
- curl GET on
/noteid/:idreturns raw note text - curl GET on
/returns a plain-text CLI usage guide - curl POST returns the full note URL
- the app header links to the GitHub repository
- app version defaults to
vdevand tag deploys replace it with the release tag
npm run verifyThis runs:
- TypeScript typecheck
- Vitest suite
- Wrangler deploy dry-run
.github/workflows/test.yml runs:
npm cinpm run typechecknpm run testnpm run deploy:dry-run
.github/workflows/deploy-worker.yml uses cloudflare/wrangler-action@v3 and deploys the Worker when you push a tag beginning with v, for example v0.0.1.
Required repository secrets:
CLOUDFLARE_API_TOKENCLOUDFLARE_ACCOUNT_ID
Optional repository variable:
CLOUDFLARE_WORKER_NAME
Release a deploy tag example:
git tag v0.0.1
git push origin v0.0.1See DEPLOY.md.
Create the default R2 buckets:
npx wrangler login
npx wrangler whoami
npx wrangler r2 bucket create note-prod
npx wrangler r2 bucket create note-previewSet GitHub Actions secrets with GitHub CLI:
gh secret set CLOUDFLARE_API_TOKEN --body 'YOUR_CLOUDFLARE_API_TOKEN'
gh secret set CLOUDFLARE_ACCOUNT_ID --body 'YOUR_CLOUDFLARE_ACCOUNT_ID'
gh variable set CLOUDFLARE_WORKER_NAME --body 'note'