To use PortPreview with an Express.js app, listen on 0.0.0.0 (or app.listen(PORT) without binding to localhost only), run npx portpreview PORT, and register the HTTPS URL for webhooks, OAuth callbacks, and API demos.
Why tunnel Express
Express remains the default HTTP layer for Node APIs and BFFs. Payment providers, CRM webhooks, and OAuth servers need a public HTTPS endpoint while you debug middleware order and raw-body parsing locally.
- Webhooks. Mount
express.raw()on webhook paths beforeexpress.json(). Details in Express webhook local testing. - OAuth. Set redirect URIs to your tunnel origin. See OAuth callback testing.
- Sharing APIs. Let mobile or frontend teams hit your local API without VPN. See share local dev server.
Quick start
- Start Express:
node server.jsornpm run devon port 3000. - Run
npx portpreview 3000. - Test
GET https://your-tunnel.portpreview.dev/health. - Configure provider webhooks to
POST https://your-tunnel.portpreview.dev/api/webhooks/....
Minimal Express server
import express from 'express';
const app = express();
const PORT = process.env.PORT ?? 3000;
app.get('/health', (_req, res) => res.json({ ok: true }));
app.listen(PORT, () => {
console.log(`Listening on http://localhost:${PORT}`);
});
Express listens on all interfaces by default. If you bind explicitly, use '0.0.0.0' so the tunnel process can forward traffic.
Trust proxy headers
Behind PortPreview your app sees X-Forwarded-Proto: https. Enable trust proxy when generating absolute URLs or secure cookies:
app.set('trust proxy', 1);
CORS for split frontends
If a React or Vue dev server on another port calls your Express API through separate tunnels, configure CORS explicitly:
import cors from 'cors';
app.use(cors({ origin: process.env.FRONTEND_TUNNEL_URL }));
Security checklist
- Verify webhook signatures before parsing JSON.
- Never expose unauthenticated admin routes on a shared tunnel.
- Stop the tunnel when finished. See tunnel security.
Express documentation covers middleware and routing. Start PortPreview free.
