[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-73813":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":25,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":35,"readmeContent":36,"aiSummary":37,"trendingCount":16,"starSnapshotCount":16,"syncStatus":38,"lastSyncTime":39,"discoverSource":40},73813,"Rin","openRin\u002FRin","openRin","🌸Publish faster with an edge-native blog powered by Cloudflare Workers, D1, and R2","https:\u002F\u002Fdocs.openrin.org",null,"TypeScript",2769,2067,10,64,0,11,19,81,33,99.55,"MIT License",false,"main",true,[27,28,29,30,31,32,33,34],"blog","bun","bunjs","cloudflare","cloudflare-workers","framework","react","web","2026-06-12 04:01:11","![Cover](.\u002Fdocs\u002Fdocs\u002Fpublic\u002Frin-logo.png)\n\nEnglish | [简体中文](.\u002FREADME_zh_CN.md)\n\n![GitHub commit activity](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fcommit-activity\u002Fw\u002FopenRin\u002FRin?style=for-the-badge)\n![GitHub branch check runs](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fcheck-runs\u002FopenRin\u002FRin\u002Fmain?style=for-the-badge)\n![GitHub top language](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flanguages\u002Ftop\u002FopenRin\u002FRin?style=for-the-badge)\n![GitHub License](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flicense\u002FopenRin\u002FRin?style=for-the-badge)\n![GitHub Actions Workflow Status](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Factions\u002Fworkflow\u002Fstatus\u002FopenRin\u002FRin\u002Fdeploy.yml?style=for-the-badge)\n\n[![Discord](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDiscord-openRin-red?style=for-the-badge&color=%236e7acc)](https:\u002F\u002Fdiscord.gg\u002FJWbSTHvAPN)\n[![Telegram](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FTelegram-openRin-red?style=for-the-badge&color=%233390EC)](https:\u002F\u002Ft.me\u002FopenRin)\n\n## Introduction\n\nRin is a modern, serverless blog platform built entirely on Cloudflare's developer platform: Pages for hosting, Workers for serverless functions, D1 for SQLite database, and R2 for object storage. Deploy your personal blog with just a domain name pointed to Cloudflare—no server management required.\n\n## Live Demo\n\nhttps:\u002F\u002Fxeu.life\n\n## Features\n\n- **Authentication & Management**: GitHub OAuth login. The first registered user becomes an administrator, while subsequent users join as regular members.\n- **Content Creation**: Write and edit articles with a rich, intuitive editor.\n- **Real-time Autosave**: Local drafts are saved automatically in real-time, with isolation between different articles.\n- **Privacy Control**: Mark articles as \"Visible only to me\" for private drafts or personal notes, synchronized across devices.\n- **Image Management**: Drag-and-drop or paste images to upload directly to S3-compatible storage (e.g., Cloudflare R2), with automatic link generation.\n- **Custom Slugs**: Assign friendly URLs like `https:\u002F\u002Fyourblog.com\u002Fabout` using custom article aliases.\n- **Unlisted Posts**: Option to keep articles out of the public homepage listing.\n- **Blogroll**: Add links to friends' blogs. The backend automatically checks link availability every 20 minutes.\n- **Comment System**: Reply to comments or moderate them with delete functionality.\n- **Webhook Notifications**: Receive real-time alerts for new comments via configurable webhooks.\n- **Featured Images**: Automatically detect the first image in an article and use it as the cover image in listings.\n- **Tag Parsing**: Input tags like `#Blog #Cloudflare` and have them automatically parsed and displayed.\n- **Type Safety**: End-to-end type safety with shared TypeScript types between client and server via `@rin\u002Fapi` package.\n- ...and more! Explore all features at https:\u002F\u002Fxeu.life.\n\n## Documentation\n\n### Quick Start\n\n```bash\n# 1. Clone the repository\ngit clone https:\u002F\u002Fgithub.com\u002FopenRin\u002FRin.git && cd Rin\n\n# 2. Install dependencies\nbun install\n\n# 3. Configure environment variables\ncp .env.example .env.local\n# Edit .env.local with your own configuration\n\n# 4. Start the development server\nbun run dev\n```\n\nVisit http:\u002F\u002Flocalhost:5173 to start hacking!\n\n### Testing\n\nRun the test suite to ensure everything works:\n\n```bash\n# Run all tests (client + server)\nbun run test\n\n# Run server tests only\nbun run test:server\n\n# Run tests with coverage\nbun run test:coverage\n```\n\n### One-Command Deployment\n\nDeploy both frontend and backend to Cloudflare with a single command:\n\n```bash\n# Deploy everything (frontend + backend)\nbun run deploy\n\n# Deploy only backend\nbun run deploy:server\n\n# Deploy only frontend\nbun run deploy:client\n```\n\n**Required environment variables:**\n\n- `CLOUDFLARE_API_TOKEN` - Your Cloudflare API token\n- `CLOUDFLARE_ACCOUNT_ID` - Your Cloudflare account ID\n\n**Optional environment variables:**\n\n- `WORKER_NAME` - Backend worker name (default: `rin-server`)\n- `PAGES_NAME` - Frontend pages name (default: `rin-client`)\n- `DB_NAME` - D1 database name (default: `rin`)\n- `R2_BUCKET_NAME` - R2 bucket name. If set, deploy derives the matching `S3_*` values automatically. If unset, no bucket is auto-selected.\n\nThe deployment script will automatically:\n\n- Create D1 database if it doesn't exist\n- Derive `S3_*` storage settings from `R2_BUCKET_NAME` only when it is explicitly set\n- Deploy backend to Workers\n- Build and deploy frontend to Pages\n- Run database migrations\n\n### GitHub Actions Workflows\n\nThe repository includes several automated workflows:\n\n- **`ci.yml`** - Runs type checking and formatting validation on every push\u002FPR\n- **`test.yml`** - Runs comprehensive tests (server + client) with coverage reporting\n- **`build.yml`** - Builds the project and triggers deployment\n- **`deploy.yml`** - Deploys to Cloudflare Pages and Workers\n\n**Required secrets (Repository Settings → Secrets and variables → Actions):**\n\n- `CLOUDFLARE_API_TOKEN` - Your Cloudflare API token with Workers and Pages permissions\n- `CLOUDFLARE_ACCOUNT_ID` - Your Cloudflare account ID\n\n**Optional configuration (Repository Settings → Secrets and variables → Variables):**\n\n- `WORKER_NAME`, `PAGES_NAME`, `DB_NAME` - Resource names\n- `NAME`, `DESCRIPTION`, `AVATAR` - Site configuration\n- `R2_BUCKET_NAME` - Specific R2 bucket to use\n\nFull documentation is available at https:\u002F\u002Fdocs.openrin.org.\n\n## Community & Support\n\n- Join our https:\u002F\u002Fdiscord.gg\u002FJWbSTHvAPN for discussions and help.\n- Follow updates on https:\u002F\u002Ft.me\u002FopenRin.\n- Found a bug or have a feature request? Please open an issue on GitHub.\n\n## Star History\n\n\u003Ca href=\"https:\u002F\u002Fstar-history.com\u002F#openRin\u002FRin&Date\">\n \u003Cpicture>\n   \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=openRin\u002FRin&type=Date&theme=dark\" \u002F>\n   \u003Csource media=\"(prefers-color-scheme: light)\" srcset=\"https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=openRin\u002FRin&type=Date\" \u002F>\n   \u003Cimg alt=\"Star History Chart\" src=\"https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=openRin\u002FRin&type=Date\" \u002F>\n \u003C\u002Fpicture>\n\u003C\u002Fa>\n\n## Contributing\n\nWe welcome contributions of all kinds—code, documentation, design, and ideas. Please check out our [contributing guidelines](https:\u002F\u002Fdocs.openrin.org\u002Fen\u002Fguide\u002Fcontribution.html) and join us in building Rin together!\n\n## License\n\n```\nMIT License\n\nCopyright (c) 2024 Xeu\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and\u002For sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n","Rin 是一个基于 Cloudflare 开发者平台构建的现代化无服务器博客平台。它利用 Pages 进行托管，Workers 实现无服务器功能，D1 作为 SQLite 数据库，R2 用于对象存储。项目核心功能包括通过 GitHub OAuth 登录进行用户认证与管理、直观的文章编辑器、实时自动保存草稿、隐私控制、图片管理和自定义文章别名等。Rin 适合需要快速部署个人博客且无需担心服务器运维的开发者或写作者使用，尤其适用于希望利用 Cloudflare 的边缘计算能力来提升网站性能和安全性的场景。",2,"2026-06-11 03:47:28","high_star"]