DEV Community

Cover image for Free ngrok alternative for async web dev - the Hookdeck CLI
Phil Leggetter for Hookdeck

Posted on • Updated on

Free ngrok alternative for async web dev - the Hookdeck CLI

ngrok is great. It's been the go-to for many a web developer who wants to be able to expose a locally running web application to the public Internet for many years. And it's still a great solution. However, as ngrok has changed in ways that have resulted in a much poorer developer experience and there are now better tools for some of the jobs that ngrok was originally the go-to for.

What's changed with ngrok?

  • ngrok used to be free and only required an account for "premium features". Now, you need an ngrok account no matter your use case.
  • There's a 1GB limit a month on data transfer (in all fairness, this should be more than enough for development)
  • The free ephemeral/random domains (the domain name changes every time you restart ngrok) have always been a bit of a pain. The first paid plan used to come with 3 subdomains but now only comes with one, making exposing multiple services at the same time more costly.

ngrok pricing, April 2021

ngrok pricing, July 2024

More broadly, Their product focus has shifted reasonably dramatically from supporting use cases such as:

  • Temporarily sharing a website that is only running on your development machine
  • Demoing an app at a hackathon without deploying
  • Developing any services that consume webhooks (HTTP callbacks) by allowing you to replay those requests
  • Debugging and understanding any web service by inspecting the HTTP traffic
  • Running networked services on machines that are firewalled off from the internet

To:

All-in-one API gateway, Kubernetes Ingress, DDoS protection, firewall, and global load balancing as a service.

So, ngrok has shifted focus away from supporting development use cases. Therefore, it's likely time to try an alternative tool that has been built to specifically support your use case.

The rest of this post will show how the Hookdeck CLI can be used to receive asynchronous events (a.k.a. webhooks) from third-party services such as Stripe, Shopify, or Twilio. If you're looking for a tool that solves the other use cases, take a look at the awesome tunneling repo.

What is synchronous web development?

As per the title of this post, the Hookdeck CLI is built to support asynchronous web development. By this, I mean requests, such as webhooks from an API service, are received and proxied onto the application running locally. However, the response from the local service is not passed back to the API service that made the request.

The Hookdeck CLI and the Hookdeck Event Gateway are built to support asynchronous messaging with event-driven applications and not the request/response paradigm. Therefore, you can't use the Hookdeck CLI to expose and serve a locally running website or request/response API. If you want to send the result of some work to another service, you should make a separate request to that service.

Using the Hookdeck CLI as a free alternative to ngrok for webhooks

The next section walks through installing the Hookdeck CLI, creating and running a local web server (which you can skip if you already have this running), creating a localtunnel using the CLI, sending test webhook events, and replaying webhooks using the Hookdeck Console.

This guide will use the Node.js runtime. If you prefer to use Python, you can run through a using the Hookdeck CLI with a Python server to receive webhooks guide.

Install the Hookdeck CLI

Via NPM:



npm i hookdeck-cli -g


Enter fullscreen mode Exit fullscreen mode

On Mac:



brew install hookdeck/hookdeck/hookdeck


Enter fullscreen mode Exit fullscreen mode

On Windows:



scoop bucket add hookdeck https://github.com/hookdeck/scoop-hookdeck-cli.git
scoop install hookdeck


Enter fullscreen mode Exit fullscreen mode

There are also instructions for installing on Linux.

Create and run a localhost Node.js web server

Open your terminal and navigate to a directory for your project.

Install Express to use as the web server:



npm i --save express


Enter fullscreen mode Exit fullscreen mode

Create a server.js file in the project root:



const express = require('express')
const app = express()

app.use(express.json());

const port = 3030;

app.post("/", (req, res) => {
    console.log({ webhook_received: new Date().toISOString(), body: req.body });
    res.json({ status: "ACCEPTED" });
});

app.listen(port, () => {
    console.log(`🪝 Server running at http://localhost:${port}`);
});


Enter fullscreen mode Exit fullscreen mode

Run the server:



node server.js


Enter fullscreen mode Exit fullscreen mode

Use the Hookdeck CLI to create a localtunnel

Run the following command in a new terminal window to create a localtunnel:



hookdeck listen 3030 my-webhook


Enter fullscreen mode Exit fullscreen mode

The output will be similar to the following:



Dashboard
👤 Console URL: https://api.hookdeck.com/signin/guest?token={token}
Sign up in the Console to make your webhook URL permanent.

Sources
🔌 my-webhook URL: https://hkdk.events/wggd60fl5cxw20

Connections
my-webhook -> my-webhook-to-cli forwarding to /

> Ready! (^C to quit)


Enter fullscreen mode Exit fullscreen mode

Test receiving a webhook with a cURL command

Run the following cURL command to act as an inbound webhook, replacing the URL with the Event URL from the Hookdeck CLI output:



curl -X POST https://hkdk.events/cnzpo680rdhejk \
  -H "Content-Type: application/json" \
  -d '{"message": "Hello, World!"}'


Enter fullscreen mode Exit fullscreen mode

The cURL command output will be similar to the following:



{"status":"SUCCESS","message":"Request handled by Hookdeck. Check your dashboard to inspect the request: https://dashboard.hookdeck.com/requests/req_[id]","request_id":"req_[id]"}%


Enter fullscreen mode Exit fullscreen mode

You will see the terminal running the Hookdeck CLI log the inbound webhook:



2024-07-09 19:06:46 [200] POST http://localhost:3030/ | https://console.hookdeck.com/?event_id={id}


Enter fullscreen mode Exit fullscreen mode

You will also see the Python server log the inbound webhook:



{
  webhook_received: '2024-07-25T10:08:22.945Z',
  body: { message: 'Hello, World!' }
}


Enter fullscreen mode Exit fullscreen mode

Trigger a test webhook using the Hookdeck Console

Open the Console URL from your terminal in your browser.

Choose a Sample Webhook Provider from the list of Example Webhooks. For example, Stripe.

Select a Sample Webhook Type from the list on the right. For example, invoice.created.

Click Send.

The Hookdeck Console will show the test webhook has been triggered. You can also inspect the webhook payload and the localhost web server response.

Trigger test webhook, inspect webhook payload, and view the localhost server response

You will see the terminal running the Hookdeck CLI log the inbound webhook:



2024-07-09 19:06:46 [200] POST http://localhost:3030/webhook | https://console.hookdeck.com/?event_id={id}


Enter fullscreen mode Exit fullscreen mode

You will also see the Python server log the inbound webhook:



{
  "id": "evt_1MhUT7E0b6fckueStwy86nfu",
  "object": "event",
  "api_version": "2022-11-15",
  "created": 1677833999,
  "data": {
    ...
  },
  "type": "invoice.created"
}


Enter fullscreen mode Exit fullscreen mode

Replay a webhook

To replay the webhook, go to the Hookdeck Console and click on the Resend to destination button.

Replay Webhook

Receive a webhook from an API platform

Copy the Event URL from the Hookdeck CLI output. You can also find the same URL in the Hookdeck Console.

Copy Hookdeck Event URL

Go to the API provider platform, such as Resend, Twilio, Shopify, or Stripe, and register the Hookdeck URL as the webhook URL with the provider.

Trigger a webhook from your selected API provider to see a log entry in the Hookdeck Console.

Inbound webhook from Vonage SMS API handled in the Hookdeck Console

You will also see the webhook logged in the Hookdeck CLI:



2024-07-09 19:45:57 [200] POST http://localhost:3030/webhook | https://console.hookdeck.com/?event_id={id}


Enter fullscreen mode Exit fullscreen mode

And by the Node.js server running in your local development environment:



{
  "to": "{to_number}",
  "from": "{from_number}",
  "channel": "sms",
  "message_uuid": "461c9502-3c2f-4af9-8862-c5a8eccf6cfe",
  "timestamp": "2024-07-09T18:45:56Z",
  "usage": {
    "price": "0.0057",
    "currency": "EUR"
  },
  "message_type": "text",
  "text": "Inbound SMS from the Vonage API",
  "context_status": "none",
  "origin": {
    "network_code": "23415"
  },
  "sms": {
    "num_messages": "1",
    "count_total": "1"
  }
}


Enter fullscreen mode Exit fullscreen mode

And that's it!

You have successfully received a webhook on your local development environment using the Hookdeck CLI. You also inspected the webhook payload and server response, and replayed a webhook using the Hookdeck Console.

Learn more about Hookdeck

This guide demonstrated how to use the Hookdeck CLI as a replacement for ngrok for local asynchronous web development. The Hookdeck CLI is free to use, and you don't need a Hookdeck account.

If you're interested in finding out more about Hookdeck including features such as transformations, and filtering, benefitting from functionality like configurable retries, and generally using Hookdeck as your reliable inbound webhook infrastructure, head to hookdeck.com

Top comments (2)

Collapse
 
quanganh206 profile image
Quang Anh Le

Take a quick tour yet. Do you support SSH to machine run Hookdeck cli like ngrok?

Collapse
 
kalyan-jyoti profile image
Kalyan Jyoti Borah

Why not devtunnels?