Skip to content

Instantly share code, notes, and snippets.

@MonteLogic
Created November 2, 2025 20:04
Show Gist options
  • Select an option

  • Save MonteLogic/2a0a90d4d2b77969cec57e9bc5cbd858 to your computer and use it in GitHub Desktop.

Select an option

Save MonteLogic/2a0a90d4d2b77969cec57e9bc5cbd858 to your computer and use it in GitHub Desktop.
// scripts/mobile-web-dev.js
const { networkInterfaces } = require('os');
const { spawn } = require('child_process');
const net = require('net');
// --- 1. Find the local IP address ---
const nets = networkInterfaces();
let localIp = 'localhost';
// Iterate over network interfaces to find the non-internal IPv4 address
for (const name of Object.keys(nets)) {
for (const netInterface of nets[name]) {
// Skip over internal (e.g. 127.0.0.1) and non-IPv4 addresses
if (netInterface.family === 'IPv4' && !netInterface.internal) {
localIp = netInterface.address;
break;
}
}
}
// --- 2. Function to check if a port is available ---
function isPortAvailable(port) {
return new Promise((resolve) => {
const server = net.createServer();
server.once('error', (err) => {
if (err.code === 'EADDRINUSE') {
resolve(false); // Port is in use
} else {
resolve(false); // Other error, assume port not available
}
});
server.once('listening', () => {
server.once('close', () => {
resolve(true); // Port is available
});
server.close();
});
server.listen(port);
});
}
// --- 3. Find an available port starting from 3000 ---
async function findAvailablePort(startPort = 3000, maxAttempts = 100) {
console.log(`\nπŸ” Looking for an available port starting from ${startPort}...`);
for (let port = startPort; port < startPort + maxAttempts; port++) {
const available = await isPortAvailable(port);
if (available) {
console.log(`βœ… Found available port: ${port}\n`);
return port;
}
process.stdout.write(` Port ${port} is in use, trying ${port + 1}...\r`);
}
throw new Error(`Could not find an available port after ${maxAttempts} attempts`);
}
// --- 4. Main function to start the server ---
async function startServer() {
try {
const port = await findAvailablePort(3000);
// Print the mobile URL
console.log(`\nπŸš€ Server starting on port ${port}...`);
console.log(`πŸ“± Access on your phone at: http://${localIp}:${port}\n`);
console.log(`πŸ’» Or on your computer at: http://localhost:${port}\n`);
// Security warning
console.log(`\nπŸ”’ SECURITY WARNING:`);
console.log(` This server is accessible to anyone on your local network (${localIp}:${port})`);
console.log(` ⚠️ Risks:`);
console.log(` - Dev server may expose stack traces and debug info`);
console.log(` - Public API endpoints: /api/generate-basic-siddur, /blog, /`);
console.log(` - Could be exploited for DoS (resource exhaustion)`);
console.log(` βœ… Protections:`);
console.log(` - Cannot directly hack your machine`);
console.log(` - Clerk auth protects most routes`);
console.log(` - Only accessible on local network (not internet)`);
console.log(` πŸ’‘ Recommendations:`);
console.log(` - Only use on trusted networks (home/work)`);
console.log(` - Stop the server when not in use`);
console.log(` - Don't use on public Wi-Fi\n`);
console.log(`\n⚠️ IMPORTANT: For Clerk to work on your phone, add this URL to your Clerk dashboard:`);
console.log(` - Go to https://dashboard.clerk.com β†’ Your App β†’ Settings β†’ Domains`);
console.log(` - Add: ${localIp}:${port}`);
console.log(` - Or add a wildcard pattern for your local network if needed\n`);
// Set environment variables for Clerk to recognize the domain
const env = {
...process.env,
NEXT_PUBLIC_CLERK_FRONTEND_API: process.env.NEXT_PUBLIC_CLERK_FRONTEND_API || '',
// Set the domain that Clerk will use for redirects
CLERK_DOMAIN: `${localIp}:${port}`,
};
// Start the Next.js dev server
const child = spawn('npx', ['next', 'dev', '-H', '0.0.0.0', '-p', port.toString()], {
// Pipe the server's output (logs, errors, etc.) to this script's console
stdio: 'inherit',
env: env,
});
// Handle errors from the child process
child.on('error', (err) => {
console.error('Failed to start Next.js server:', err);
process.exit(1);
});
// Handle process exit
child.on('exit', (code) => {
if (code !== 0) {
console.error(`Next.js server exited with code ${code}`);
process.exit(code);
}
});
} catch (error) {
console.error('Error starting server:', error.message);
process.exit(1);
}
}
// Start the server
startServer();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment