Claude
Skills
Sign in
Back

mobile-debugging

Included with Lifetime
$97 forever

Remote JavaScript console access and debugging on mobile devices. Use when debugging web pages on phones/tablets, accessing console errors without desktop DevTools, testing responsive designs on real devices, or diagnosing mobile-specific issues. Covers Eruda, vConsole, Chrome/Safari remote debugging, and cloud testing platforms.

Cloud & DevOps

What this skill does


# Mobile debugging methodology

Patterns for accessing JavaScript console and debugging web pages on mobile devices without traditional desktop DevTools.

## Quick-start: Inject console on any page

### Eruda bookmarklet (recommended)

Add this as a bookmark on your mobile browser, then tap it on any page:

```javascript
javascript:(function(){var script=document.createElement('script');script.src='https://cdn.jsdelivr.net/npm/eruda';document.body.append(script);script.onload=function(){eruda.init();}})();
```

### vConsole bookmarklet

```javascript
javascript:(function(){var script=document.createElement('script');script.src='https://unpkg.com/vconsole@latest/dist/vconsole.min.js';document.body.append(script);script.onload=function(){new VConsole();}})();
```

## In-page console tools

### Eruda setup

Eruda provides a full DevTools-like experience in a floating panel. Eruda 3.x (3.4.3 current as of 2026-05) is the right baseline; it ships ES2020 syntax and assumes a modern mobile browser.

```html
<!-- CDN (development only) -->
<script src="https://cdn.jsdelivr.net/npm/eruda"></script>
<script>eruda.init();</script>

<!-- Conditional loading (recommended for production) -->
<script>
(function() {
    var src = 'https://cdn.jsdelivr.net/npm/eruda';
    // Only load when ?eruda=true or localStorage flag set
    if (!/eruda=true/.test(window.location) &&
        localStorage.getItem('active-eruda') !== 'true') return;

    var script = document.createElement('script');
    script.src = src;
    script.onload = function() { eruda.init(); };
    document.body.appendChild(script);
})();
</script>
```

```javascript
// NPM installation
// npm install eruda --save-dev

import eruda from 'eruda';

// Initialize with options
eruda.init({
    container: document.getElementById('eruda-container'),
    tool: ['console', 'elements', 'network', 'resources', 'info'],
    useShadowDom: true,
    autoScale: true
});

// Add custom buttons
eruda.add({
    name: 'Clear Storage',
    init($el) {
        $el.html('<button>Clear All Storage</button>');
        $el.find('button').on('click', () => {
            localStorage.clear();
            sessionStorage.clear();
            console.log('Storage cleared');
        });
    }
});

// Remove when done
eruda.destroy();
```

**Eruda features:**
- Console (logs, errors, warnings)
- Elements (DOM inspector)
- Network (XHR/fetch requests)
- Resources (localStorage, cookies, sessionStorage)
- Sources (page source code)
- Info (page/device information)
- Snippets (saved code snippets)

### vConsole setup

Lighter weight alternative, official tool for WeChat debugging.

```html
<!-- CDN -->
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script>
var vConsole = new VConsole();
</script>
```

```javascript
// NPM
// npm install vconsole

import VConsole from 'vconsole';

// Initialize with options
const vConsole = new VConsole({
    theme: 'dark',
    onReady: function() {
        console.log('vConsole is ready');
    },
    log: {
        maxLogNumber: 1000
    }
});

// Dynamic configuration
vConsole.setOption('log.maxLogNumber', 5000);

// Destroy when done
vConsole.destroy();
```

**vConsole features:**
- Log panel (console.log, info, warn, error)
- System panel (device info)
- Network panel (XHR, fetch)
- Element panel (DOM tree)
- Storage panel (cookies, localStorage)

### Comparison: Eruda vs vConsole

| Feature | Eruda | vConsole |
|---------|-------|----------|
| Size | ~100KB | ~85KB |
| DOM Editing | Yes | View only |
| Network Details | Full | Basic |
| Plugin System | Yes | Yes |
| Dark Theme | Via plugin | Built-in |
| Best For | Full debugging | Quick logging |

## Native remote debugging

### Chrome DevTools (Android)

```bash
# 1. Enable USB debugging on Android
#    Settings → Developer Options → USB Debugging = ON

# 2. Connect via USB to computer

# 3. Open Chrome on computer, navigate to:
#    chrome://inspect#devices

# 4. Enable "Discover USB devices"

# 5. Accept debugging prompt on Android device

# 6. Click "Inspect" next to the page you want to debug
```

**Port forwarding for localhost:**
```bash
# In chrome://inspect, click "Port forwarding"
# Add: localhost:3000 → localhost:3000
# Now Android Chrome can access your dev server at localhost:3000
```

**Android 11+ wireless debugging (no USB needed):**
```bash
# 1. On the Android device:
#    Settings → Developer Options → Wireless debugging = ON
#    Tap "Pair device with pairing code"
#    Note the IP:PORT and 6-digit code shown

# 2. On the computer (Android Platform Tools 30.0.0+):
adb pair <DEVICE_IP>:<PAIRING_PORT>
# Enter the 6-digit code when prompted

# 3. Connect to the debug port (different from pairing port):
adb connect <DEVICE_IP>:<DEBUG_PORT>

# 4. Verify and proceed to chrome://inspect#devices as usual:
adb devices
```

Wireless debugging persists across reboots once paired, but the `adb connect` step is needed each session.

### Safari Web Inspector (iOS)

```bash
# 1. On iPhone/iPad:
#    Settings → Safari → Advanced → Web Inspector = ON

# 2. On Mac:
#    Safari → Preferences → Advanced → "Show Develop menu" = ON

# 3. Connect device via USB (or enable Wi-Fi debugging)

# 4. Open Safari on Mac:
#    Develop → [Device Name] → [Page to debug]

# Wireless debugging (after initial USB setup):
#    Develop → [Device] → Connect via Network
```

### Firefox Remote Debugging (Android)

```bash
# 1. On Android Firefox:
#    Settings → Advanced → Remote debugging = ON

# 2. On Desktop Firefox:
#    Open about:debugging

# 3. Connect Android via USB

# 4. Enable USB devices in about:debugging

# 5. Click "Connect" next to your device
```

## iOS debugging without Mac

### Using ios-webkit-debug-proxy

```bash
# Install on Windows (via Scoop)
scoop bucket add extras
scoop install ios-webkit-debug-proxy

# Install on Linux
sudo apt-get install ios-webkit-debug-proxy

# Install on Mac
brew install ios-webkit-debug-proxy

# Run the proxy
ios_webkit_debug_proxy -f chrome-devtools://devtools/bundled/inspector.html

# Connect to http://localhost:9221 to see connected devices
```

### Commercial: Inspect.dev

Inspect.dev provides iOS debugging from Windows/Linux with a familiar DevTools interface.

```bash
# Download from https://inspect.dev/
# 1. Install application
# 2. Connect iOS device via USB
# 3. Enable Web Inspector on iOS
# 4. Inspect.dev auto-detects pages
# 5. Click to open DevTools interface
```

## Cloud testing platforms

### LambdaTest (freemium)

```python
# LambdaTest provides real device cloud with console access
# Free tier: 100 minutes/month

import requests

# LambdaTest REST API for automation
LAMBDATEST_API = "https://api.lambdatest.com/automation/api/v1"

# For manual testing:
# 1. Go to https://www.lambdatest.com/
# 2. Select device/browser
# 3. Enter URL
# 4. DevTools available in toolbar

# Selenium/Playwright integration for automated console capture
from playwright.sync_api import sync_playwright

def test_on_lambdatest():
    with sync_playwright() as p:
        # Connect to LambdaTest
        browser = p.chromium.connect(
            f"wss://cdp.lambdatest.com/playwright?capabilities="
            f"{{\"browserName\":\"Chrome\",\"platform\":\"android\"}}"
        )
        page = browser.new_page()

        # Capture console logs
        logs = []
        page.on('console', lambda msg: logs.append(msg.text()))

        page.goto('https://example.com')
        browser.close()

        return logs
```

### BrowserStack

```python
# BrowserStack: $29/month+, 10,000+ real devices
# Selenium 4 removed DesiredCapabilities — pass capabilities via Options instead.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def get_browserstack_driver():
    """Create BrowserStack WebDriver with console logging."""

    options = Options()
    bstack_options = {
        'deviceName': 'Samsung Galaxy S21',
        'osVersion': '11.0',
        'realMobile': 'true',
     

Related in Cloud & DevOps