# Testing Webhooks Locally with Node.js and Express You can always test webhooks using a hosted service like Azure. But if you either don’t have access—or just don’t feel like dealing with that—this approach is a simple and effective alternative. --- ## Prerequisites Most of these instructions are written with **macOS** in mind (sorry in advance). You’ll need: - **Node.js** - **Homebrew** → [[Homebrew Install]] --- ## Set Up a Basic Express Server Start by creating a directory wherever you prefer. ```zsh mkdir webhook-express cd webhook-express npm init -y npm install express ``` Create your main application file: ```zsh touch index.js vi index.js ``` --- ## `index.js` Paste the following into `index.js`: ```javascript // index.js const express = require("express"); const app = express(); const PORT = process.env.PORT || 3000; // Parse JSON bodies (ideal for most webhook providers) app.use(express.json()); // Health check route app.get("/", (req, res) => { res.status(200).send("OK - Express server is running"); }); // Webhook endpoint app.post("/webhook", (req, res) => { console.log("✅ Webhook received!"); console.log("Headers:", req.headers); console.log("Body:", req.body); // Respond quickly so the webhook provider doesn't time out res.sendStatus(200); }); app.listen(PORT, () => { console.log(`✅ Express listening at http://localhost:${PORT}`); console.log(`➡️ Webhook endpoint: http://localhost:${PORT}/webhook`); }); ``` --- ## Run the Server Start the Express server: ```zsh node index.js ``` --- ## Test the Webhook Locally In a **separate terminal tab**, send a test POST request: ```shell curl -X POST http://localhost:3000/webhook -H "Content-Type: application/json" -d '{"event":"test","id":123}' ``` You should see output similar to this in your server terminal: ![[Pasted image 20260307213827.png]] --- ## Expose the Webhook to the Internet (LocalTunnel) To allow external services to reach your local webhook, install **localtunnel**: ```zsh npm install -g localtunnel ``` Since your Express app is listening on port **3000**, expose it like this: ```zsh localtunnel --port 3000 ``` Or shorthand: ```zsh lt --port 3000 ``` LocalTunnel will print a public URL, something like: ``` https://busy-phones-shout.loca.lt ``` --- ## Test from the Public Internet POST to the public endpoint: ``` https://busy-phones-shout.loca.lt/webhook ``` Any requests sent there will now hit your local Express server, and you’ll see the same headers and body logged as before. --- ## ✅ Summary - ✅ Lightweight Express webhook receiver - ✅ Logs headers and payloads - ✅ Works locally and publicly - ✅ No cloud services required Perfect for quick testing, demos, or when you just want to see what a webhook is actually sending you.