Setting Up CNCjs on a Raspberry Pi for Web-Based CNC Control
OctoPrint turned a spare Raspberry Pi into a headless, browser-controlled front end for 3D printers years ago; CNCjs does the same job for GRBL-based CNC routers. Instead of running a sender application on a dedicated laptop tethered to the machine, a Pi running CNCjs sits permanently wired to the router over USB and serves a full control interface — jogging, G-code streaming, a live position readout, and macros — to any browser on the network, freeing your actual workstation and letting you check job progress from across the shop.
Why Run It on a Pi Instead of a Laptop
A dedicated headless Pi means the CNC connection stays live and doesn't depend on a laptop staying awake, on the same Wi-Fi network reliably, or being physically present at the machine. It also means the USB-to-GRBL link is a short, fixed cable rather than something that gets unplugged and moved around with a laptop, which cuts down on the loose-connection G-code streaming hiccups that come from a cable getting bumped mid-job.
Installation
Start from a fresh Raspberry Pi OS Lite install (headless is fine — you'll never need a monitor on this Pi) with SSH enabled during imaging. Update the system, then install Node.js via NodeSource's setup script rather than the often-outdated version in the default Raspberry Pi OS repos, since CNCjs needs a reasonably current Node release. Install CNCjs itself globally through npm; the whole install is a handful of commands and typically finishes in a few minutes on a Pi 4 or Pi 5.
Run CNCjs once manually first to confirm it starts and serves its web UI on port 8000 by default, then set it up as a systemd service so it starts automatically on boot and restarts if it ever crashes — a controller you have to SSH in and manually relaunch after every power blip defeats the point of a headless setup.
Connecting to Your CNC Router
Plug your GRBL controller (a Wolfpawn 4040 Pro or similar) into the Pi over USB, then open CNCjs's web UI from another machine on the network and select the correct serial port and baud rate (115200 is GRBL's common default) from the connection panel. Once connected, CNCjs's dashboard gives you jogging controls, a G-code file loader with a visual toolpath preview, a macro panel for repeat commands (homing, common probe sequences), and a live console showing raw GRBL responses if you need to debug something.
Remote Access Considerations
Keep CNCjs itself reachable only on your local network by default — it has no built-in authentication in a default install, and exposing it directly to the internet means anyone who finds the port can jog your machine. If you want to check job status from outside the house, put it behind a VPN rather than a port-forward: our Tailscale on Raspberry Pi guide covers exactly this pattern and works well for reaching a shop Pi remotely without exposing anything publicly.
CNCjs vs. Other GRBL Senders
SoftwareAccess ModelBest For CNCjsWeb browser, any device on network (or VPN)Headless Pi setups, checking job status from across the shop gSenderDesktop app on the machine tethered to the CNCLocal, dedicated-laptop setups; simpler for a single always-there operator Universal G-code Sender (UGS)Desktop app, cross-platformAdvanced macro/scripting users, long-running open-source project LightBurn (GRBL module)Desktop appShops already using LightBurn for a combo laser/CNC workflowSafety Notes
A web UI reachable from across the room or the network does not replace physical presence during a cut — browser-based control adds real latency compared to a directly-tethered sender, and an emergency stop clicked in a browser is slower than a hand on a physical e-stop button. Keep a physical, hardwired emergency stop on the machine itself regardless of how you're sending G-code, and never start an unfamiliar or newly-written job and walk away expecting to monitor it purely through the web dashboard from another room. Treat remote access as a convenience for checking progress and queuing the next job, not as a substitute for being present when a cut actually starts.
Once it's running, a Pi-hosted CNCjs setup quietly removes the "which laptop has the sender installed" friction from a shop with more than one person using the same machine, and it's a natural pairing if you're already running a Pi for OctoPrint or Home Assistant elsewhere in the shop — one more headless service, one more browser tab, same reliable Pi doing the job.
Related Guides
- Mounting a Diode Laser Module on Your CNC Router: Dual-Use Gantry Conversion
- CNC Touch Probes for Desktop Routers: Wiring, Tool Length Offset, and Work Zero Setup
- Homing and Limit Switches for GRBL CNC Routers: Wiring, Configuration, and Safe Homing Cycles
- Z-Mapping and Surface Probing for CNC Routing on Warped or Uneven Stock: Getting Consistent Carve Depth
- Adding a 4th-Axis Rotary to the Wolfpawn 4040 Pro: Wiring and Your First Cut
- Build a Physical Jog Pendant for GRBL CNC Routers: Rotary Encoder, Feed Override, and Wireless Option
- Wolfpawn 4040 Pro — Machine Reference & Connection Guide
- CNC Router — GRBL Command Reference