Turn a computer's webcam and microphone into a simple local-network monitoring camera.
CamOnLAN runs a small Node.js server on the computer that owns the webcam. Open the host page on that computer, start the camera, then scan the displayed QR code from a phone, tablet, or another computer on the same local network.
No account. No cloud dashboard. No CCTV/NVR configuration. The project is intentionally focused on temporary local monitoring with hardware you already have.
CamOnLAN is a convenience monitoring tool, not a safety-critical baby monitor, alarm system, or professional security system.
- Webcam video streamed with WebRTC
- Optional one-way microphone audio from host to viewers
- QR-code connection from phones and tablets
- Manual access by LAN address + access code
- No user-facing room IDs
- Automatic LAN-address recommendation
- Manual network-interface selector when Windows/VPN/VM adapters confuse auto-detection
- Configurable access code
- Configurable maximum of 1–5 viewers (default: 2)
- One independent WebRTC connection per viewer
- Viewer slots released when devices disconnect
- Heartbeat cleanup for stale WebSocket connections
- Reopening the same viewer can replace its stale connection even when the viewer limit is full
- New host tab can replace a stale/older local host tab
- Automatic viewer reconnection after brief network interruptions
- Optional local recording, off by default
- Fullscreen viewer and audio mute controls
- Windows BAT launcher with human-readable comments and prerequisite checks
- Small built-in test suite using Node's standard test runner
- Node.js 18 or newer
- npm (normally installed with Node.js)
- A webcam
- Optional microphone
- A modern browser
- A modern phone, tablet, or desktop browser
- Connection to the same local Wi-Fi/LAN as the host
The host page should be opened as:
http://localhost:3000
localhost is important because browsers allow camera/microphone APIs there without requiring you to configure HTTPS certificates for this local utility.
From a terminal in the CamOnLAN folder:
npm install
npm startThen open:
http://localhost:3000
On the host page:
- Choose the camera and microphone you want to use.
- Leave Share microphone audio enabled if you want sound.
- Click Start monitoring.
- Allow the browser's camera/microphone permission request.
- Scan the QR code from a phone on the same LAN.
Press Ctrl+C in the terminal to stop the CamOnLAN server.
Windows users can also double-click:
Start CamOnLAN.bat
The BAT file is deliberately plain text and heavily commented. You can open it in Notepad and inspect every command before running it. On supported Windows systems it also uses PowerShell only for cosmetic colored status messages; if PowerShell is unavailable, the launcher falls back to ordinary text.
It performs only these steps:
- Opens the launcher inside a persistent Command Prompt so startup errors remain visible instead of disappearing in a flashing window.
- Changes the working directory to the CamOnLAN folder.
- Verifies that the BAT file is still inside the complete project folder.
- Checks whether Node.js is installed.
- Checks that Node.js is version 18 or newer.
- Checks whether npm is available.
- Runs
npm installon the first launch whennode_modulesdoes not exist. - Runs
npm start.
It does not install Node.js, create a Windows service, modify your power settings, or silently add Windows Firewall rules.
The launcher stops immediately and displays a message similar to:
CamOnLAN could not start.
Node.js was not found on this computer.
Please install Node.js, then run "Start CamOnLAN.bat" again.
Download Node.js from: https://nodejs.org/
CamOnLAN requires Node.js 18 or newer.
The launcher keeps this message visible until you press a key. After installing Node.js, simply run the BAT file again.
The first time Node.js listens for connections from your LAN, Windows may show a firewall permission dialog.
CamOnLAN needs incoming access on your private/home network so that your phone can reach the server running on the computer.
Recommended choice:
- Private networks: allow
- Public networks: not required
CamOnLAN does not automatically modify Windows Firewall rules.
If you deny the prompt, the host page may still work on the computer while your phone cannot reach it.
CamOnLAN does not change your computer's sleep or hibernation settings.
If the host computer sleeps, hibernates, shuts down, leaves the network, or closes the browser tab that owns the camera, monitoring stops.
Before leaving CamOnLAN running for a long period, make sure your normal operating-system power settings will keep the computer awake for as long as you need it.
CamOnLAN deliberately hides WebRTC's internal session identifiers from normal users.
The normal workflow is:
Computer
|
| Start monitoring
v
Camera + microphone
|
| QR code
v
Phone on same LAN
|
v
Live WebRTC stream
You can connect in either of two ways.
The host displays a QR code containing the selected LAN address plus the current access code.
Scan it from the viewer device. CamOnLAN reads the code from the URL and then removes it from the visible address/history entry so the credential does not remain unnecessarily exposed in the address bar.
Open the LAN address shown by the host, for example:
http://192.168.1.37:3000
Then enter the displayed access code.
Computers often have more than one IPv4 address.
For example, Windows machines may expose addresses belonging to:
- Wi-Fi
- Ethernet
- WSL
- Hyper-V
- Docker
- VirtualBox
- VMware
- VPN clients
CamOnLAN ranks likely physical/private LAN adapters ahead of common virtual adapters, but no automatic heuristic can be perfect on every computer.
The host interface therefore always includes a network selector.
If the QR code does not work from your phone:
- Look at the network dropdown.
- Select the Wi-Fi or Ethernet address used by your actual LAN.
- Make sure the displayed address resembles the computer's real private LAN address, often something like
192.168.x.xor10.x.x.x. - Scan the regenerated QR code.
CamOnLAN remembers the selected address while the server is running.
CamOnLAN uses one access code rather than separate usernames, accounts, passwords, and room IDs.
The default code is randomly generated on first launch.
You may replace it from the host settings with your own code.
The current configuration is stored in:
config.json
This file is intentionally excluded from Git through .gitignore because it contains your local access code.
The example structure is shown in:
config.example.json
CamOnLAN supports between 1 and 5 simultaneous viewers.
The default maximum is:
2 viewers
Each viewer has its own WebRTC peer connection to the host browser.
Increasing the viewer count can increase CPU usage and network bandwidth on the host because the computer must serve additional WebRTC peers.
The host interface displays the current count, for example:
1 / 2 viewers
Normal browser-tab closes release the viewer slot immediately when the WebSocket closes.
CamOnLAN also uses heartbeat checks to remove clients that disappear without a clean close, such as when:
- a browser crashes
- a phone goes offline
- Wi-Fi changes
- a device sleeps
- connectivity is abruptly lost
Each viewer browser stores a local client ID. If the same viewer reconnects while an older connection with that ID is still considered present, CamOnLAN replaces the stale connection rather than rejecting the user simply because the viewer limit is full.
Audio is one-way:
Host microphone -> viewers
There is no viewer-to-host microphone channel and no intercom/push-to-talk feature.
Audio sharing can be disabled before starting monitoring.
The viewer can also mute playback locally without affecting other viewers.
Recording is off by default. CamOnLAN never starts recording merely because monitoring starts.
When the host browser supports the MediaRecorder API, a Record button appears after monitoring starts.
CamOnLAN saves long recordings as 30-minute parts instead of allowing one file to grow indefinitely. The visible recording timer remains continuous while files rotate in the background. The last part is naturally shorter if you stop before the next 30-minute boundary.
Each part is created with its own MediaRecorder, which keeps the parts independently playable. At a segment boundary CamOnLAN prepares the next recorder (and, where supported, its destination file) while the current part is still recording. It then stops the old recorder, starts the prepared recorder as soon as the browser reports the old one stopped, and only after capture has resumed does it finish flushing/closing/downloading the previous file.
This keeps filesystem and download work out of the recording handoff. A browser still does not guarantee a mathematically gapless MediaRecorder stop/start transition, so a very short browser-scheduling/encoder handoff gap can remain at the boundary. CamOnLAN deliberately avoids overlapping two recorders because that would add duplicate footage and extra encoding load.
Files are named approximately like:
CamOnLAN_20260816_19-30-00_part-001.webm
CamOnLAN_20260816_20-00-00_part-002.webm
CamOnLAN_20260816_20-30-00_part-003.webm
The actual extension depends on a recording MIME type supported by the browser.
If the browser exposes the File System Access directory picker, clicking Record asks you to choose a folder once. CamOnLAN then creates each 30-minute recording part directly inside that folder without asking again at every boundary.
This keeps browser memory usage bounded and is the preferred mode for long recordings.
If the directory picker is not available, CamOnLAN uses browser downloads instead.
Only the current segment is accumulated in browser memory. When a 30-minute segment ends, that part is downloaded and CamOnLAN immediately continues with a fresh segment.
For recordings longer than one part, the browser may display a one-time prompt asking whether the site is allowed to download multiple files. Allow that prompt if you want unattended segment downloads to continue.
When you click Stop & save recording, the current partial segment is downloaded as well.
CamOnLAN does not upload recordings to a cloud service.
CamOnLAN asks the browser which recording MIME types it supports rather than assuming every browser produces the same format.
Depending on the browser and operating system, the resulting file may be WebM or MP4.
CamOnLAN/
|
|-- pages/
| |-- host.html # Host/computer UI
| `-- viewer.html # Phone/viewer UI
|
|-- public/
| |-- css/
| | `-- app.css # Shared interface styles
| `-- js/
| |-- host.js # Host page orchestration/UI
| |-- host-peer-manager.js
| | # One WebRTC peer per viewer
| |-- recording.js # MediaRecorder + local save/download behavior
| |-- viewer.js # Viewer page orchestration/UI
| `-- viewer-peer.js # Viewer WebRTC peer
|
|-- src/
| |-- config.js # Access code/viewer-limit config
| |-- network.js # LAN adapter discovery/ranking
| |-- session-manager.js # Host/viewer lifecycle rules
| `-- signaling.js # WebSocket signaling + heartbeat
|
|-- test/
| |-- config.test.js
| |-- network.test.js
| `-- session-manager.test.js
|
|-- server.js # HTTP server and route composition
|-- Start CamOnLAN.bat # Readable Windows launcher
|-- config.example.json
|-- package.json
|-- .gitignore
|-- LICENSE
`-- README.md
CamOnLAN intentionally avoids unnecessary layers.
Composes the HTTP server, local-only host/settings endpoints, static files, QR-code generation, and WebSocket signaling.
Owns config validation/defaults and persistence.
Finds private IPv4 interfaces and ranks likely Wi-Fi/Ethernet adapters ahead of common virtual interfaces.
Owns connection policy:
- one current host browser
- configurable viewer limit
- access-code checking
- same-viewer replacement
- disconnect cleanup
Keeping these rules separate from WebSocket transport makes them easy to test.
Owns WebSocket connections, heartbeats, and message forwarding between the host and viewers.
- The host browser owns the camera/microphone
MediaStream. - Each viewer gets a separate host-side
RTCPeerConnection. - WebRTC and recording remain browser-side because the browser owns the camera/microphone stream.
There is no attempt to route webcam media through Node.js.
CamOnLAN is designed for a trusted local network, not exposure directly to the public Internet.
Camera/microphone media is sent through WebRTC between the browser peers.
The Node.js server handles signaling information; it does not act as a video recording server or cloud relay.
Sensitive host operations such as retrieving/changing settings and generating QR details are restricted to local requests from the host computer.
A LAN viewer cannot simply query the settings API to retrieve the configured access code.
CamOnLAN does not require a CamOnLAN account or hosted CamOnLAN backend.
The app is intended to function inside your LAN without depending on an application cloud service.
The access code is protection against casual/unauthorized viewers on the same LAN. CamOnLAN should not be treated as a hardened authentication system suitable for exposing the server directly to the Internet.
Do not port-forward CamOnLAN from your router to the public Internet.
The host browser may request:
- camera permission
- microphone permission, if audio sharing is enabled
- a directory selection when you explicitly start recording in a browser that supports direct directory access
CamOnLAN does not bypass browser permission controls.
The normal way to edit settings is through the host interface.
The persisted configuration is intentionally tiny:
{
"accessCode": "123456",
"maxViewers": 2
}Valid viewer limits are 1 through 5.
The access code must be 4–64 characters and may contain letters, numbers, dots, underscores, and hyphens.
If config.json does not exist, CamOnLAN generates one automatically with safe defaults.
Install dependencies:
npm installStart CamOnLAN:
npm startRun tests:
npm testThe tests use Node's built-in node:test module, so there is no test-framework dependency.
The test suite covers:
- configuration validation
- configuration creation/persistence
- LAN-interface ranking
- loopback detection
- incorrect access-code rejection
- viewer-limit cleanup
- stale same-viewer replacement at capacity
- local-only host role and host replacement
Browser/WebRTC camera tests still require real browsers/devices and are not currently automated by this small test suite.
Check:
- Both devices are connected to the same LAN/Wi-Fi.
- The host computer is awake.
- CamOnLAN is still running in its terminal window.
- Windows Firewall allows Node.js on private networks.
- The selected network address belongs to the real Wi-Fi/Ethernet connection rather than WSL, Docker, VirtualBox, Hyper-V, VMware, or a VPN.
- Your Wi-Fi does not enable client/AP isolation, which prevents wireless devices from talking directly to each other.
Try manually opening the displayed URL on the phone before troubleshooting WebRTC. If the page itself cannot load, the issue is network/server reachability rather than WebRTC.
Use the Network address selector on the host page and choose your real Wi-Fi/Ethernet IPv4 address.
The QR code updates automatically.
Make sure the host is opened as:
http://localhost:3000
Also check operating-system and browser camera permissions.
Another application may already have exclusive control of some webcam drivers.
Close another viewer or increase Maximum viewers from host settings.
Disconnected clients are heartbeat-cleaned automatically. Reopening the same viewer should replace its previous stale connection.
Mobile operating systems may suspend browser networking when a browser is backgrounded or the phone goes to sleep.
CamOnLAN attempts to reconnect when the page becomes active/reachable again, but it cannot override mobile operating-system background policies.
The browser may be blocking multiple automatic downloads. Look for a browser permission/prompt and allow multiple downloads for the CamOnLAN local page.
Not every browser supports the File System Access directory picker. In those browsers CamOnLAN downloads each completed 30-minute part instead. For long recordings, the browser may ask you once to allow multiple automatic downloads.
CamOnLAN is not intended to grow into a complete CCTV/NVR platform.
Current non-goals include:
- RTSP/IP-camera ingestion
- ONVIF device discovery
- CCTV management
- cloud accounts
- cloud recording
- public-Internet remote access
- motion/AI detection
- push notifications
- two-way intercom audio
Those features may be valuable in other products, but adding all of them here would undermine CamOnLAN's main advantage: a small, understandable tool for temporarily monitoring an existing computer webcam over a local network.
CamOnLAN is licensed under the MIT License. See LICENSE.