{"id":32867314,"url":"https://github.com/o-az/unplugin-cloudflare-tunnel","last_synced_at":"2026-05-07T09:31:36.359Z","repository":{"id":321684878,"uuid":"1086761446","full_name":"o-az/unplugin-cloudflare-tunnel","owner":"o-az","description":"A plugin that automatically creates and manages Cloudflare tunnels for local development.","archived":false,"fork":false,"pushed_at":"2026-04-14T23:53:13.000Z","size":483,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-15T00:16:50.357Z","etag":null,"topics":["cloudflared","dev","rolldown","rollup","tunnel","unplugin","vite","webpack"],"latest_commit_sha":null,"homepage":"https://npmx.dev/unplugin-cloudflare-tunnel","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/o-az.png","metadata":{"files":{"readme":".github/README.md","changelog":"CHANGELOG.md","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":null,"dco":null,"cla":null}},"created_at":"2025-10-30T21:41:07.000Z","updated_at":"2026-04-14T22:20:31.000Z","dependencies_parsed_at":"2025-10-31T01:21:08.604Z","dependency_job_id":null,"html_url":"https://github.com/o-az/unplugin-cloudflare-tunnel","commit_stats":null,"previous_names":["o-az/unplugin-cloudflare-tunnel"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/o-az/unplugin-cloudflare-tunnel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-az%2Funplugin-cloudflare-tunnel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-az%2Funplugin-cloudflare-tunnel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-az%2Funplugin-cloudflare-tunnel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-az%2Funplugin-cloudflare-tunnel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/o-az","download_url":"https://codeload.github.com/o-az/unplugin-cloudflare-tunnel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o-az%2Funplugin-cloudflare-tunnel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32731223,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-07T02:14:30.463Z","status":"ssl_error","status_checked_at":"2026-05-07T02:14:29.405Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cloudflared","dev","rolldown","rollup","tunnel","unplugin","vite","webpack"],"created_at":"2025-11-09T06:01:17.596Z","updated_at":"2026-05-07T09:31:36.353Z","avatar_url":"https://github.com/o-az.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# unplugin-cloudflare-tunnel\n\n[![Open on npmx.dev](https://npmx.dev/api/registry/badge/version/unplugin-cloudflare-tunnel)](https://npmx.dev/package/unplugin-cloudflare-tunnel) [![pkg.pr.new](https://pkg.pr.new/badge/o-az/unplugin-cloudflare-tunnel)](https://pkg.pr.new/~/o-az/unplugin-cloudflare-tunnel)\n\nA plugin that automatically creates and manages Cloudflare tunnels for local development. Available for:\n\n- [Vite](https://vite.dev)\n- [Rspack](https://rspack.rs)\n- [Webpack](https://webpack.js.org)\n- [esbuild](https://esbuild.github.io)\n- [Rollup](https://rollupjs.org)\n- [Rolldown](https://rolldown.rs)\n- [Astro](https://astro.build) \u003csup\u003esoon\u003c/sup\u003e\n- [Farm](https://farmfe.org) \u003csup\u003esoon\u003c/sup\u003e\n\n\u003e [!NOTE]\n\u003e\n\u003e This is under active development. If you have any suggestions, I'm all ears, please open an issue.\n\n## Install\n\nunplugin-cloudflare-tunnel\n\n```bash\nnpm add unplugin-cloudflare-tunnel\n```\n\n## Usage\n\n### Modes\n\nThe plugin supports two modes:\n\n- **Quick mode**: temporary `trycloudflare.com` URL, no Cloudflare credentials required\n- **Named mode**: persistent tunnel on your own hostname\n\nMode selection rules:\n\n- `mode: 'quick'` → always quick mode\n- `mode: 'named'` → always named mode, requires `hostname`\n- if `mode` is omitted:\n  - `hostname` provided → named mode\n  - otherwise → quick mode\n\n### Common options\n\n- `mode?: 'quick' | 'named'`\n- `protocol?: 'http2' | 'quic'` — defaults to `http2` for better local dev reliability\n- `logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'fatal'`\n- `port?: number`\n- `logFile?: string`\n- `debug?: boolean`\n- `enabled?: boolean`\n\n\u003e [!TIP]\n\u003e\n\u003e For esbuild, Rollup, and Rolldown dev usage, set `port` explicitly so the tunnel can target the local dev server.\n\n### Quick mode example\n\n```ts\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport CloudflareTunnel from 'unplugin-cloudflare-tunnel/vite'\n\nexport default defineConfig({\n  plugins: [\n    CloudflareTunnel({\n      mode: 'quick',\n      protocol: 'http2'\n    })\n  ]\n})\n```\n\n### Named mode example\n\n```ts\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport CloudflareTunnel from 'unplugin-cloudflare-tunnel/vite'\n\nexport default defineConfig({\n  plugins: [\n    CloudflareTunnel({\n      mode: 'named',\n      hostname: 'dev.example.com',\n      apiToken: process.env.CLOUDFLARE_API_TOKEN,\n      protocol: 'http2'\n    })\n  ]\n})\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eVite\u003c/summary\u003e\u003cbr\u003e\n\n```ts\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport CloudflareTunnel from 'unplugin-cloudflare-tunnel/vite'\n\nexport default defineConfig({\n  plugins: [\n    CloudflareTunnel({\n      mode: 'quick'\n    })\n  ]\n})\n```\n\nExample in [./example/vite.config.ts](../example/vite.config.ts): `cd example \u0026\u0026 bun run dev:vite`\n\n\u003cbr\u003e\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eRspack\u003c/summary\u003e\u003cbr\u003e\n\n```ts\n// rspack.config.mjs\nimport CloudflareTunnel from 'unplugin-cloudflare-tunnel/rspack'\n\nexport default {\n  /* ... */\n  plugins: [CloudflareTunnel()]\n}\n```\n\nExample in [./example/rspack.config.ts](../example/rspack.config.ts): `cd example \u0026\u0026 bun run dev:rspack`\n\n\u003cbr\u003e\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eWebpack\u003c/summary\u003e\u003cbr\u003e\n\n```ts\n// webpack.config.js\nconst CloudflareTunnel = require('unplugin-cloudflare-tunnel/webpack')\n\nmodule.exports = {\n  /* ... */\n  plugins: [CloudflareTunnel()]\n}\n```\n\nExample in [./example/webpack.config.ts](../example/webpack.config.ts): `cd example \u0026\u0026 bun run dev:webpack`\n\n\u003cbr\u003e\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eesbuild\u003c/summary\u003e\u003cbr\u003e\n\n```ts\n// esbuild.config.ts\nimport { context } from 'esbuild'\nimport CloudflareTunnel from 'unplugin-cloudflare-tunnel/esbuild'\n\nconst ctx = await context({\n  entryPoints: ['./main.mjs'],\n  bundle: true,\n  outdir: './dist',\n  outExtension: { '.js': '.mjs' },\n  define: {\n    __VIA_TOOL__: JSON.stringify('esbuild')\n  },\n  plugins: [\n    CloudflareTunnel({\n      hostname: 'dev.example.com',\n      apiToken: process.env.CLOUDFLARE_API_TOKEN,\n      port: 6420\n    })\n  ]\n})\n\nawait ctx.watch()\nawait ctx.serve({ port: 6420, servedir: './dist' })\n```\n\nExample in [./example/esbuild.config.ts](../example/esbuild.config.ts): `cd example \u0026\u0026 bun run esbuild.config.ts`\n\n\u003e [!NOTE]\n\u003e\n\u003e esbuild dev usage requires an explicit `port` option.\n\n\u003cbr\u003e\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eRollup\u003c/summary\u003e\u003cbr\u003e\n\n```ts\n// rollup.config.ts\nimport { defineConfig } from 'rollup'\nimport CloudflareTunnel from 'unplugin-cloudflare-tunnel/rollup'\n\nexport default defineConfig({\n  /* ... */\n  plugins: [\n    CloudflareTunnel({\n      hostname: 'dev.example.com',\n      apiToken: process.env.CLOUDFLARE_API_TOKEN,\n      port: 6421\n    })\n  ]\n})\n```\n\nExample in [./example/rollup.config.ts](../example/rollup.config.ts): `cd example \u0026\u0026 bun run dev:rollup`\n\n\u003e [!NOTE]\n\u003e\n\u003e Rollup dev usage requires an explicit `port` option.\n\n\u003cbr\u003e\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eRolldown\u003c/summary\u003e\u003cbr\u003e\n\n```ts\n// rolldown.config.ts\nimport { defineConfig } from 'rolldown'\nimport CloudflareTunnel from 'unplugin-cloudflare-tunnel/rolldown'\n\nexport default defineConfig({\n  /* ... */\n  plugins: [\n    CloudflareTunnel({\n      hostname: 'dev.example.com',\n      apiToken: process.env.CLOUDFLARE_API_TOKEN,\n      port: 6422\n    })\n  ]\n})\n```\n\nExample in [./example/rolldown.config.ts](../example/rolldown.config.ts): `cd example \u0026\u0026 bun run dev:rolldown`\n\n\u003e [!NOTE]\n\u003e\n\u003e Rolldown dev usage requires an explicit `port` option.\n\n\u003cbr\u003e\u003c/details\u003e\n\n## Virtual Module: Access Tunnel URL\n\n\u003e [!NOTE]\n\u003e\n\u003e This feature is available in supported dev integrations, including Vite, Webpack, Rspack, esbuild, Rollup, and Rolldown.\n\nThe plugin provides a virtual module that allows you to access the tunnel URL in your application code during development. This is useful for:\n\n- Displaying the tunnel URL in your UI\n- Sharing the URL with users\n- Debugging and logging\n- Building features that need the public URL\n\n### Usage\n\n```ts\nimport { getTunnelUrl } from 'virtual:unplugin-cloudflare-tunnel'\n\n// Get the current tunnel URL\nconst tunnelUrl = getTunnelUrl()\nconsole.log('Public tunnel URL:', tunnelUrl)\n\n// Example: Copy tunnel URL to clipboard\nconst shareButton = document.getElementById('share')\nshareButton.onclick = () =\u003e {\n  navigator.clipboard.writeText(getTunnelUrl())\n  alert('Tunnel URL copied!')\n}\n```\n\n### TypeScript Support\n\nTo get TypeScript support for the virtual module, add a reference to the types:\n\n```ts\n// In your tsconfig.json or a .d.ts file\n/// \u003creference types=\"unplugin-cloudflare-tunnel/virtual\" /\u003e\n```\n\nOr create a `virtual.d.ts` file in your project:\n\n```ts\n/// \u003creference types=\"unplugin-cloudflare-tunnel/virtual\" /\u003e\n```\n\n### Return Value\n\n- **Quick tunnel mode**: Returns a random URL like `https://abc-123.trycloudflare.com`\n- **Named tunnel mode**: Returns your custom domain URL like `https://dev.example.com`\n- **Plugin disabled**: Returns an empty string `\"\"`\n\n### Notes on modes\n\n- Named-only options such as `hostname`, `apiToken`, `accountId`, `zoneId`, `tunnelName`, `dns`, `ssl`, and `cleanup` are only valid in named mode.\n- Quick mode ignores Cloudflare account setup entirely and creates an ephemeral tunnel.\n- `protocol` applies to both quick and named modes.\n\n### Notes\n\n- The virtual module is only available during development mode\n- In production builds, the virtual module will not be available\n- The URL is automatically updated if the port changes or tunnel restarts\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-az%2Funplugin-cloudflare-tunnel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fo-az%2Funplugin-cloudflare-tunnel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-az%2Funplugin-cloudflare-tunnel/lists"}