npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

cf-tunnel

v0.1.9

Published

Easily manage Cloudflare Tunnels in your Node.js applications.

Downloads

489

Readme

cf-tunnel 모

Easily manage Cloudflare Tunnels in your Node.js applications.

npm version npm downloads codecov license

Why Use cf-tunnel?

cf-tunnel provides significant advantages over alternatives like cloudflared-tunnel or untun:

  • Consistent URLs: Unlike Quick Tunnels that use random URLs, cf-tunnel uses Locally-managed tunnels with user-defined hostnames – critical for OAuth/SSO authentication flows.
  • Config-Driven Approach: Manage tunnels entirely from your configuration file – no manual CLI commands needed.
  • Automatic Lifecycle Management: Creates, configures, and cleans up tunnels and DNS records automatically.
  • Clean Exit Handling: Automatically removes tunnels and DNS records when your application exits.

When to Choose cf-tunnel

Choose cf-tunnel when you need:

  • A persistent, custom hostname for your local development environment
  • Authentication flows that require stable callback URLs
  • Automated tunnel management within your application lifecycle
  • Complete cleanup of resources when your application exits

Features

  • 🚀 Simple CLI interface
  • ⚙️ Flexible configuration (JS/JSON/YAML)
  • 🔄 Automatic tunnel cleanup
  • 🔒 Secure credential management
  • 📂 OS-specific config paths
  • 📝 TypeScript support

CLI Usage

Installation

# ✨ Auto-detect
npx nypm install cf-tunnel

# npm
npm install cf-tunnel

# yarn
yarn add cf-tunnel

# pnpm
pnpm install cf-tunnel

# bun
bun install cf-tunnel

# deno
deno install cf-tunnel

Run with default config (tunnel.config.{yml,yaml,json,js})

cf-tunnel

Or with custom config path

cf-tunnel -c custom-tunnel.config.js
cf-tunnel -c path/to/my-config.js
cf-tunnel -c /absolute/path/config.yml
cf-tunnel -c ./relative/config.json

Or directly with JSON configuration string

cf-tunnel --json '{"cfToken":"your-token","tunnelName":"my-tunnel","ingress":[{"hostname":"app.example.com","service":"http://localhost:3000"}]}'
# npm
npx cf-tunnel

# pnpm
pnpm dlx cf-tunnel

# bun
bunx cf-tunnel

# deno
deno run -A npm:cf-tunnel

Configuration File

When no config file is specified, the CLI looks for these files in order:

  1. tunnel.config.yml
  2. tunnel.config.yaml
  3. tunnel.config.json
  4. tunnel.config.js

Example configuration file:

// tunnel.config.js
export default {
  cfToken: process.env.CF_TOKEN, // Cloudflare API token
  tunnelName: "my-tunnel",
  ingress: [
    {
      hostname: "app.example.com",
      service: "http://localhost:3000",
    },
    // Add more services as needed
  ],
  // Optional: Control how existing resources are handled
  removeExistingDns: false, // Set to true to automatically remove existing DNS records
  removeExistingTunnel: false, // Set to true to automatically remove existing tunnel
};

Programmatic Usage

Installation

# ✨ Auto-detect
npx nypm install cf-tunnel

# npm
npm install cf-tunnel

# yarn
yarn add cf-tunnel

# pnpm
pnpm install cf-tunnel

# bun
bun install cf-tunnel

# deno
deno install cf-tunnel

Usage

ESM (Node.js, Bun, Deno)

import { cfTunnel, defineTunnelConfig } from "cf-tunnel";

const config = defineTunnelConfig({
  cfToken: process.env.CF_TOKEN,
  tunnelName: "my-tunnel",
  ingress: [
    {
      hostname: "app.example.com",
      service: "http://localhost:3000",
    },
  ],
  removeExistingDns: true,
  removeExistingTunnel: true,
});

// Start the tunnel
await cfTunnel(config);

Lifecycle Management

cf-tunnel manages the entire lifecycle of your Cloudflare Tunnel:

  1. Setup Phase:

    • If removeExistingTunnel: true, removes any existing tunnel with the same name
    • If removeExistingDns: true, removes DNS records for hostnames in your config
    • Creates a new tunnel with the specified name
    • Configures DNS records for all ingress services
  2. Running Phase:

    • Runs the tunnel in the foreground
    • Keeps the process alive until interrupted
  3. Cleanup Phase (triggered on process exit):

    • Automatically removes all DNS records created for the tunnel
    • Deletes the tunnel from Cloudflare
    • Removes local credential files

This automatic lifecycle management ensures no orphaned resources are left in your Cloudflare account.


Configuration Options

| Option | Type | Required | Default | Description | | -------------------- | --------- | -------- | --------------------- | ------------------------------------------------------- | | cfToken | string | Yes | process.env.CF_TOKEN | Cloudflare API token | | tunnelName | string | Yes | - | Name for the tunnel | | ingress | Ingress[] | Yes | - | Array of services to expose | | cloudflaredConfigDir | string | No | OS-specific default* | Path to cloudflared config directory | | removeExistingDns | boolean | No | false | If true, removes existing DNS records | | removeExistingTunnel | boolean | No | false | If true, removes any existing tunnel with the same name |

* Default config directory:

  • Windows: %AppData%/Local/cloudflared
  • macOS: ~/Library/Application Support/cloudflared
  • Linux: ~/.cloudflared

Ingress Configuration

Each ingress entry requires:

  • hostname: The public hostname for the service (e.g., "app.example.com")
  • service: The local service URL (e.g., "http://localhost:3000")

Additional ingress options are supported as per Cloudflare's documentation.

Examples

Check out the examples directory for usage examples:

import { cfTunnel, defineTunnelConfig } from "cf-tunnel";

const tunnelConfig = defineTunnelConfig({
  cfToken: process.env.CF_TOKEN,
  tunnelName: "test-tunnel",
  ingress: [{ hostname: "test.com", service: "localhost:3000" }],
});

await cfTunnel(tunnelConfig);

Development

  1. Clone this repository
  2. Install latest LTS version of Node.js
  3. Enable Corepack using corepack enable
  4. Install dependencies using pnpm install
  5. Run interactive tests using pnpm dev

License

Published under the MIT license.

Contributors

Published under the MIT license. Made by @jasenmichael ❤️


🤖 auto updated with automd