{"id":50962374,"url":"https://github.com/harshil1712/codeflare","last_synced_at":"2026-06-18T15:33:35.300Z","repository":{"id":342280597,"uuid":"1161769634","full_name":"harshil1712/codeflare","owner":"harshil1712","description":"Generate screenshots of your code snippet","archived":false,"fork":false,"pushed_at":"2026-03-05T17:08:02.000Z","size":830,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-05T20:46:08.485Z","etag":null,"topics":["ai-search","browser-rendering","cloudflare-workers","r2","screenshot"],"latest_commit_sha":null,"homepage":"https://codeflare.h-demo.workers.dev/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/harshil1712.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-19T13:54:23.000Z","updated_at":"2026-03-06T16:25:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/harshil1712/codeflare","commit_stats":null,"previous_names":["harshil1712/codeflare"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/harshil1712/codeflare","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harshil1712%2Fcodeflare","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harshil1712%2Fcodeflare/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harshil1712%2Fcodeflare/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harshil1712%2Fcodeflare/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/harshil1712","download_url":"https://codeload.github.com/harshil1712/codeflare/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harshil1712%2Fcodeflare/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34497366,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-search","browser-rendering","cloudflare-workers","r2","screenshot"],"created_at":"2026-06-18T15:33:32.306Z","updated_at":"2026-06-18T15:33:35.291Z","avatar_url":"https://github.com/harshil1712.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CodeFlare\n\nGenerate beautiful, shareable code screenshots — powered by Cloudflare Workers.\n\nPaste your code, customize the styling, and export a pixel-perfect PNG rendered by a headless browser at 2× device pixel ratio. Authenticated users can save screenshots to Cloudflare R2, browse their gallery, and search across saved screenshots using AI.\n\n[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/harshil1712/codeflare)\n\n\u003c!-- Add a screenshot or demo GIF here --\u003e\n\u003cimg src=\"./codeflare.png\" alt=\"CodeFlare demo\" width=\"100%\" /\u003e\n\n---\n\n## Features\n\n- **Live preview** — real-time syntax-highlighted preview as you type\n- **20 languages** — TypeScript, JavaScript, Python, Rust, Go, Java, C, C++, C#, HTML, CSS, JSON, YAML, Markdown, Bash, SQL, PHP, Ruby, and more\n- **10 themes** — GitHub Dark/Light, One Dark Pro, Dracula, Nord, Monokai, Solarized Dark/Light, Catppuccin Mocha, Vitesse Dark\n- **13 background presets** — gradients from Sunset to Midnight, plus transparent\n- **Configurable styling** — font size, padding, card background color and opacity, line numbers, window title\n- **Server-side PNG rendering** — Puppeteer via Cloudflare Browser Rendering at 2× DPI\n- **Flexible export** — download only, save to R2, or save and download\n- **Authentication** — email/password sign-up and sign-in via Better Auth, backed by Cloudflare D1\n- **Screenshot gallery** — authenticated users can browse, preview, and delete their saved screenshots\n- **AI-powered search** — semantic search across saved screenshots using Cloudflare AutoRAG\n- **Rate limiting** — 10 requests per 60 seconds per IP\n\n---\n\n## Tech Stack\n\n| Layer               | Technology                                |\n| ------------------- | ----------------------------------------- |\n| Frontend            | React 19, TypeScript, Vite + SWC          |\n| Routing             | TanStack Router                           |\n| Syntax highlighting | Shiki (frontend preview + worker render)  |\n| UI components       | @cloudflare/kumo, @phosphor-icons/react   |\n| Code editor         | react-simple-code-editor                  |\n| Authentication      | Better Auth                               |\n| Database            | Cloudflare D1 (SQLite) via Drizzle ORM    |\n| Backend             | Hono 4 on Cloudflare Workers              |\n| Screenshot engine   | @cloudflare/puppeteer (Browser Rendering) |\n| Storage             | Cloudflare R2                             |\n| AI search           | Cloudflare AutoRAG                        |\n| Rate limiting       | Cloudflare Rate Limiting binding          |\n| Deployment          | Cloudflare Pages + Workers (Wrangler)     |\n\n---\n\n## Supported Languages\n\n| Language   | Language   | Language | Language |\n| ---------- | ---------- | -------- | -------- |\n| TypeScript | JavaScript | TSX      | JSX      |\n| Python     | Rust       | Go       | Java     |\n| C          | C++        | C#       | HTML     |\n| CSS        | JSON       | YAML     | Markdown |\n| Bash       | SQL        | PHP      | Ruby     |\n\n---\n\n## Local Development\n\n### Prerequisites\n\n- Node.js 18+\n- A Cloudflare account with Workers, R2, D1, Browser Rendering, and AI access\n- Wrangler CLI (`npm install -g wrangler` or use the local dev dependency)\n\n### Setup\n\n```bash\ngit clone https://github.com/harshil1712/codeflare\ncd codeflare\nnpm install\n```\n\nCopy the example environment file and fill in your values (see [Environment Variables](#environment-variables)):\n\n```bash\ncp .env.example .env\n```\n\n### Run the dev server\n\n```bash\nnpm run dev\n```\n\nThis starts the Vite dev server at `http://localhost:5173` with HMR. The frontend and worker are bundled together via the `@cloudflare/vite-plugin`.\n\n### Notes on Cloudflare bindings in development\n\nThe worker uses five Cloudflare bindings (`BROWSER`, `SCREENSHOTS`, `RATE_LIMITER`, `AI`, `DB`). In local development these are provided by Wrangler's local simulation, with one exception:\n\n- `BROWSER` is configured with `\"remote\": true` in `wrangler.jsonc`, so screenshot generation makes live calls to Cloudflare's Browser Rendering service during dev.\n- `SCREENSHOTS` (R2), `RATE_LIMITER`, `DB` (D1), and `AI` are simulated locally by Wrangler.\n\nYou must be logged in to Wrangler for remote bindings to work:\n\n```bash\nnpx wrangler login\n```\n\n---\n\n## Database Setup\n\nCodeFlare uses Cloudflare D1 for authentication data (users, sessions, accounts). Migrations are managed with Drizzle ORM.\n\n### Apply migrations locally\n\n```bash\nnpm run db:migrate\n```\n\n### Regenerate migrations after schema changes\n\n```bash\nnpm run db:generate\n```\n\n### Regenerate the Better Auth schema\n\nIf you modify authentication options in `lib/auth.ts`, regenerate the auth schema:\n\n```bash\nnpm run auth:generate\n```\n\n---\n\n## Environment Variables\n\nThe following secrets are required. Set them in a `.env` file for local development, and as Wrangler secrets for production.\n\n| Variable                 | Description                                                                   |\n| ------------------------ | ----------------------------------------------------------------------------- |\n| `BETTER_AUTH_SECRET`     | Random secret used to sign auth tokens (min 32 chars)                         |\n| `BETTER_AUTH_URL`        | The canonical URL of your deployed app (e.g. `https://codeflare.example.com`) |\n| `CLOUDFLARE_ACCOUNT_ID`  | Your Cloudflare account ID (for D1 HTTP access via Drizzle)                   |\n| `CLOUDFLARE_DATABASE_ID` | The D1 database ID from `wrangler.jsonc`                                      |\n| `CLOUDFLARE_D1_TOKEN`    | A Cloudflare API token with D1 read/write permissions                         |\n\nTo add secrets to your deployed worker:\n\n```bash\nnpx wrangler secret put BETTER_AUTH_SECRET\nnpx wrangler secret put BETTER_AUTH_URL\n# etc.\n```\n\n---\n\n## Deployment\n\n### 1. Create Cloudflare resources\n\nBefore deploying, ensure the following exist in your Cloudflare account:\n\n**R2 Bucket**\n```bash\nnpx wrangler r2 bucket create codeflare-screenshots\n```\n\n**D1 Database**\n```bash\nnpx wrangler d1 create codeflare\n```\n\nUpdate the `database_id` in `wrangler.jsonc` with the ID returned by this command, then apply migrations to production:\n\n```bash\nnpx wrangler d1 migrations apply DB --remote\n```\n\n**Rate Limiting namespace** — configured in `wrangler.jsonc` under `ratelimits`. The `namespace_id` must match a rate limit namespace in your account. Update `wrangler.jsonc` with the correct ID if needed.\n\n**Browser Rendering** — enabled automatically for your account; no manual creation required.\n\n**AutoRAG** — create an AutoRAG instance named `codeflare-search` in the Cloudflare dashboard (AI \u003e AutoRAG), then ensure the `AI` binding in `wrangler.jsonc` points to your account's AI gateway.\n\n### 2. Set secrets\n\n```bash\nnpx wrangler secret put BETTER_AUTH_SECRET\nnpx wrangler secret put BETTER_AUTH_URL\nnpx wrangler secret put CLOUDFLARE_ACCOUNT_ID\nnpx wrangler secret put CLOUDFLARE_DATABASE_ID\nnpx wrangler secret put CLOUDFLARE_D1_TOKEN\n```\n\n### 3. Deploy\n\n```bash\nnpm run deploy\n```\n\nThis runs `tsc -b` (type-check), `vite build` (bundle frontend + worker), then `wrangler deploy` to push everything to Cloudflare.\n\n### Wrangler bindings reference (`wrangler.jsonc`)\n\n| Binding        | Type              | Details                       |\n| -------------- | ----------------- | ----------------------------- |\n| `BROWSER`      | Browser Rendering | `remote: true`                |\n| `SCREENSHOTS`  | R2 Bucket         | `codeflare-screenshots`       |\n| `RATE_LIMITER` | Rate Limit        | 10 req / 60 s per IP          |\n| `AI`           | AI binding        | Used for AutoRAG search       |\n| `DB`           | D1 Database       | `codeflare` (auth + app data) |\n\nAfter any changes to `wrangler.jsonc`, regenerate the Worker type definitions:\n\n```bash\nnpm run cf-typegen\n```\n\n---\n\n## Routes\n\n| Path        | Description                                   | Auth required |\n| ----------- | --------------------------------------------- | ------------- |\n| `/`         | Main code editor and screenshot export        | No            |\n| `/gallery`  | Browse, preview, and delete saved screenshots | Yes           |\n| `/login`    | Email/password sign-in                        | No            |\n| `/register` | Create a new account                          | No            |\n\n---\n\n## API Reference\n\n### `POST /api/screenshot`\n\nGenerates a PNG screenshot of the provided code.\n\n**Request body** (`application/json`):\n\n| Field             | Type      | Required | Description                                                                    |\n| ----------------- | --------- | -------- | ------------------------------------------------------------------------------ |\n| `code`            | `string`  | Yes      | The source code to render (max 50 KB)                                          |\n| `language`        | `string`  | Yes      | Programming language for syntax highlighting (e.g. `\"typescript\"`, `\"python\"`) |\n| `theme`           | `string`  | Yes      | Shiki theme ID (see [Themes](#themes-theme-field))                             |\n| `background`      | `string`  | Yes      | CSS gradient string for the outer background                                   |\n| `padding`         | `number`  | Yes      | Padding (px) around the code card                                              |\n| `fontSize`        | `number`  | Yes      | Font size (px) for the code                                                    |\n| `showLineNumbers` | `boolean` | Yes      | Whether to render line numbers                                                 |\n| `windowTitle`     | `string`  | Yes      | Title shown in the macOS-style window title bar                                |\n| `cardBackground`  | `string`  | Yes      | CSS color value for the code card background                                   |\n| `action`          | `string`  | Yes      | Export action: `\"download_only\"`, `\"r2_only\"`, or `\"r2_and_download\"`          |\n\n**Responses:**\n\n| Scenario                             | Status | Body                                 |\n| ------------------------------------ | ------ | ------------------------------------ |\n| `download_only` or `r2_and_download` | `200`  | PNG binary (`image/png`)             |\n| `r2_only`                            | `200`  | `{ \"key\": \"\u003cr2-object-key\u003e\" }`       |\n| Validation error                     | `400`  | `{ \"error\": \"\u003cmessage\u003e\" }`           |\n| Rate limit exceeded                  | `429`  | `{ \"error\": \"Rate limit exceeded\" }` |\n| Server error                         | `500`  | `{ \"error\": \"\u003cmessage\u003e\" }`           |\n\n**Example:**\n\n```bash\ncurl -X POST https://\u003cyour-worker\u003e.workers.dev/api/screenshot \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"code\": \"const hello = \\\"world\\\";\",\n    \"language\": \"typescript\",\n    \"theme\": \"github-dark\",\n    \"background\": \"linear-gradient(135deg, #141e30 0%, #243b55 100%)\",\n    \"padding\": 40,\n    \"fontSize\": 14,\n    \"showLineNumbers\": true,\n    \"windowTitle\": \"hello.ts\",\n    \"cardBackground\": \"rgba(30,30,30,0.85)\",\n    \"action\": \"download_only\"\n  }' --output screenshot.png\n```\n\n---\n\n### `GET /api/screenshots`\n\nReturns a list of screenshots saved by the authenticated user.\n\n**Auth:** Required (session cookie)\n\n**Response** (`200`):\n\n```json\n[\n  {\n    \"key\": \"user_abc123/2026-03-01T12:00:00Z_uuid.png\",\n    \"uploaded\": \"2026-03-01T12:00:00.000Z\",\n    \"size\": 204800\n  }\n]\n```\n\n---\n\n### `GET /api/screenshots/:key`\n\nServes a specific saved screenshot as a PNG.\n\n**Auth:** Required (must be the owner)\n\n**Response:** PNG binary (`image/png`) or `404` / `403`.\n\n---\n\n### `DELETE /api/screenshots/:key`\n\nDeletes a saved screenshot from R2.\n\n**Auth:** Required (must be the owner)\n\n**Response:** `200 { \"success\": true }` or `404` / `403`.\n\n---\n\n### `GET /api/search?q=\u003cquery\u003e`\n\nSearches saved screenshots using Cloudflare AutoRAG.\n\n**Auth:** Required (session cookie)\n\n**Query params:**\n\n| Param | Description                   |\n| ----- | ----------------------------- |\n| `q`   | Natural language search query |\n\n**Response** (`200`): AutoRAG search result object.\n\n---\n\n### `POST /api/auth/*` · `GET /api/auth/*`\n\nBetter Auth handler for sign-up, sign-in, sign-out, and session management. Refer to the [Better Auth documentation](https://www.better-auth.com) for the full sub-route reference.\n\n---\n\n## Configuration Reference\n\n### Themes (`theme` field)\n\n| ID                 | Name             |\n| ------------------ | ---------------- |\n| `github-dark`      | GitHub Dark      |\n| `github-light`     | GitHub Light     |\n| `one-dark-pro`     | One Dark Pro     |\n| `dracula`          | Dracula          |\n| `nord`             | Nord             |\n| `monokai`          | Monokai          |\n| `solarized-dark`   | Solarized Dark   |\n| `solarized-light`  | Solarized Light  |\n| `catppuccin-mocha` | Catppuccin Mocha |\n| `vitesse-dark`     | Vitesse Dark     |\n\n### Background presets\n\n| Name             | Description         |\n| ---------------- | ------------------- |\n| Cloudflare Light | Warm white gradient |\n| Cloudflare Dark  | Dark warm gradient  |\n| Sunset           | Red to yellow       |\n| Ocean            | Blue to purple      |\n| Purple Haze      | Aqua to pink        |\n| Midnight         | Deep navy           |\n| Forest           | Teal to green       |\n| Peach            | Warm peach tones    |\n| Sky              | Cyan to blue        |\n| Candy            | Pink to yellow      |\n| Dark             | Near-black grey     |\n| Light            | Soft grey-white     |\n| Transparent      | No background       |\n\n### Export actions (`action` field)\n\n| Value             | Behavior                                         |\n| ----------------- | ------------------------------------------------ |\n| `download_only`   | Returns PNG directly in the response body        |\n| `r2_only`         | Saves PNG to R2; returns `{ \"key\": \"...\" }`      |\n| `r2_and_download` | Saves to R2 and returns PNG in the response body |\n\n---\n\n## Contributing\n\nContributions are welcome.\n\n1. Fork the repository and create a feature branch\n2. Make your changes, following the code style in `AGENTS.md`\n3. Run lint and build before opening a PR:\n   ```bash\n   npm run lint\n   npm run build\n   ```\n4. Open a pull request with a clear description of what changed and why\n\n**Note:** There is no test framework configured. Type correctness (`tsc -b`) and linting (`eslint .`) are the primary automated checks.\n\n---\n\n## License\n\n[MIT](./LICENSE) — Copyright (c) 2026 Harshil Agrawal\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharshil1712%2Fcodeflare","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fharshil1712%2Fcodeflare","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharshil1712%2Fcodeflare/lists"}