HL Logo
CNC Laser

CNC Laser Control with HL Logo

An open-source web interface to easily and efficiently control CNC laser machines.


A Progressive Web App (PWA) to control CNC or laser machines using the Web Serial API

Draw, process images, generate G-code, and communicate with controllers and full offline support

⚠ Optimized for Google Chrome in Dark Mode



HobbyLASER is aimed at users of CNC machines, engravers, and plotters—particularly self-built or budget models. It was developed to fill the gap between the basic software offered by low-cost machine manufacturers and professional software solutions, with a focus on hobby use and rapid prototyping.

Simple but not trivial, it uses a hybrid system of tools and scripts to create and transform vector drawings, process images, and generate files ready to be sent to microcontrollers. HobbyLASER requires no installation, as it runs entirely in the browser—no dependencies, no drivers—using the Web Serial API for USB communication.

It should be considered a constant work in progress, but thanks to its nature as a Progressive Web App (PWA), updates are available immediately upon release.

Currently, it can import text-based files with the following extensions: .svg, .dxf, .gcode, .nc, and raster images in .png, .jpg, or .jpeg format. The .svg format is an open standard, but only single-path drawings using absolute commands are accepted. For example, a file exported from Inkscape will be rejected if it contains multiple paths, groups, or uses relative commands.

Main Features

  • Interactive Drawing:   Create vector designs directly in your browser.
  • Raster Image Support:   Load PNG or JPG files and prepare them for engraving.
  • Custom Fonts:   Import your own fonts and enhance your creative control.
  • Offline Support:   Use the full app functionality without an internet connection.
  • G-code Generation:   Convert images or drawings into G-code and send it to your machine.
  • Installable as App:   Install the web app like a native application on desktop.
  • Dark Mode Ready:   Fully optimized for low-light environments and eye comfort.

Firmware & Web Serial

Firmware Compatibility

  • GRBL v1.1f or later (recommended)
  • GRBL-based boards: Arduino Uno + CNC Shield, Woodpecker, EleksMaker, etc.

ℹ GRBL is an open-source firmware for CNC motion control using Arduino-based boards. Learn more

Communication

  • USB connection using the Web Serial API
  • Requires Google Chrome or other Chromium-based browsers
  • No additional drivers or software needed

⚠ Make sure your firmware accepts serial commands via USB.
Default baud rate: 115200

Web Serial API

  • Direct access to serial ports from the browser
  • Full configuration (baud rate, data bits, parity, stop bits)
  • Asynchronous communication using the Streams API
  • Automatic detection of connect/disconnect events
  • Requires user permission for security
  • Works in Chromium-based browsers only

How to Run Locally

  1. Clone the repository:
    git clone https://github.com/marco-f/PWA-HobbyLASER.git
  2. Navigate into the folder:
    cd PWA-HobbyLASER
  3. Start a local server:
    npm install -g http-server
    http-server
  4. "
  5. (Optional) Install the app as a PWA from the browser

UI (User Interface)
UI (interfaccia utente)

Below is a screenshot of the interface in action. It shows the drawing tools, image processing options, and G-code preview – all in the browser.
Di seguito una schermata dell'interfaccia in azione. Mostra gli strumenti di disegno, le opzioni di elaborazione immagini e l'anteprima del G-code – tutto nel browser.

App Screenshot


The user interface is divided into five key areas, designed to deliver maximum precision and control in a single environment.
L’interfaccia utente si articola in cinque aree chiave, studiate per offrire massima precisione e controllo in un unico ambiente.

Rulers in millimeters
Righelli in millimetri

Rulers graduated in millimeters run along the top and left edges of the workspace for quick measurements and accurate element placement.
Ai bordi superiore e sinistro dell’area di lavoro scorrono righelli graduati in millimetri, per misurazioni rapide e posizionamenti accurati di ogni elemento grafico.

Modular grid
Griglia modulare

A customizable grid (adjustable spacing and line weight) is visible in the workspace background, supporting “snap-to-grid” to facilitate alignment and scaling of objects.
Sullo sfondo dell’area di lavoro è visibile una griglia personalizzabile (passo e spessore regolabili) che supporta lo “snap-to-grid”, facilitando l’allineamento e il ridimensionamento degli oggetti.

Dynamic guides
Linee guida dinamiche

Guides can be instantiated by clicking the intersection point of the horizontal and vertical rulers. Once generated, they become dynamically adjustable by dragging from their intersection node—an essential feature for defining precise custom axes and reference grids, particularly in complex layout compositions or for segmenting the workspace into functional zones.
Le guide possono essere generate facendo clic sul punto di intersezione tra i righelli orizzontale e verticale. Una volta create, risultano regolabili dinamicamente trascinando il nodo di intersezione—una funzione essenziale per definire assi personalizzati e griglie di riferimento precise, particolarmente utile in composizioni di layout complesse o per suddividere l’area di lavoro in zone funzionali.

Configurable work area
Area di lavoro configurabile

The blank area originates at coordinate 0/0 and can be dynamically resized by dragging the handle located at the intersection of the rulers. The updated dimensions are automatically transmitted to the GRBL controller, ensuring precise alignment between the digital workspace and the physical machine coordinates.
L'area vuota ha origine nella coordinata 0/0 ed è ridimensionabile dinamicamente trascinando la maniglia posta all'intersezione dei righelli. Le dimensioni aggiornate vengono trasmesse automaticamente al controllore GRBL, garantendo un allineamento preciso tra l’area di lavoro digitale e le coordinate macchina reali.

Rendering area
Area di rendering

Dedicated space for real-time visualization of the toolpath and job simulation. Accurately reflects transformations, material boundaries, and machine behavior during execution.
Spazio dedicato alla visualizzazione in tempo reale del percorso utensile e alla simulazione del lavoro. Rappresenta con precisione trasformazioni, limiti del materiale e comportamento macchina durante l'esecuzione.

Scripting area
Area di scripting

With simple keyboard shortcuts you can quickly create regular polygons, text, ellipses, rectangles, or start the polyline drawing tool.
Con semplici combinazioni da tastiera si creano rapidamente poligoni regolari, testi e ellissi e rettangoli, oppure si avvia lo strumento di disegno polyline.

Through scripting (JavaScript), by invoking API functions, you can apply complex transformations (translation, scaling, skew, offset, ...) to objects or combine them with boolean operations (union, difference, intersection, XOR) programmatically.
A mezzo scripting (JavaScript) possiamo, richiamando funzioni API, applicare agli oggetti trasformazioni complesse (traslazione, scalatura, skew, offset, ...) o combinarli con operazioni booleane (union, difference, intersection, XOR) in modo programmatico.

Log and console area
Area di log e console

A dedicated panel displays real-time status messages, errors, and confirmations, each line timestamped for immediate debugging and comprehensive operation tracking.
Pannello dedicato alla visualizzazione in tempo reale di messaggi di stato, errori e conferme, ogni riga corredata di timestamp per un debug immediato e completo tracciamento delle operazioni.

Raster image manipulation
Manipolazione delle immagini raster

Import PNG/JPG directly onto the canvas and adjust size, gamma, position, rotation, flip, and via script apply filters (dithering, halftone) or cropping.
Importare PNG/JPG direttamente nel canvas e regolare misura, gamma, posizione, rotazione, flip e da script applicare filtri (dithering, halftone) o ritaglio.

Start bitmap-to-vector conversion (using potrace.js), obtaining SVG paths that can then be treated like normal vector objects (resized, transformed, or combined with boolean operations).
Avviare la conversione bitmap→vettoriale (tramite potrace.js), ottenendo tracciati SVG che possono poi essere trattati come normali oggetti vettoriali (ridimensionati, trasformati, o combinati con operazioni booleane).



After creating or manipulating the path with the .gcode() function, you can access the section dedicated to generating, previewing, and sending the G-code to your machine.
Dopo aver creato o manipolato il tracciato con la funzione .gcode(), si può accedere alla sezione dedicata alla generazione, visualizzazione e invio del G-code alla macchina.

G‑code Generation Modal
Finestra Generazione G‑code

Use this modal to configure all the parameters for cutting or engraving: set minimum and maximum laser power, travel and engraving speeds, number of passes, and more. Click ‘Create’ to generate the G‑code preview or choose ‘Download’ to save the file directly.
Usa questa finestra per configurare tutti i parametri di taglio o incisione: imposta potenza minima e massima del laser, velocità di viaggio e incisione, numero di passate e altro. Clicca ‘Create’ per generare l’anteprima del G‑code o ‘Download’ per salvare il file.

G‑code Viewer & GRBL Controls
Visualizzatore G‑code e Controlli GRBL

In this modal you can preview the generated G‑code in a 3D simulator and manage your machine connection via GRBL. Use the buttons to connect/disconnect, send the G‑code line by line, pause, resume or stop the job at any time.
In questa finestra puoi visualizzare il G‑code generato in un simulatore 3D e gestire la connessione alla macchina tramite GRBL. Usa i pulsanti per connetterti/disconnetterti, inviare il G‑code riga per riga, mettere in pausa, riprendere o arrestare il lavoro in qualsiasi momento.

  • Connect: open the serial port to the controller.
    Connect: apre la porta seriale verso il controller.
  • Send: stream the G‑code to the machine with flow control.
    Send: invia il G‑code alla macchina con controllo di flusso.
  • Pause / Resume: temporarily halt or continue the execution.
    Pause / Resume: sospendi o continua temporaneamente l’esecuzione.
  • Stop: immediately halt the machine (emergency stop).
    Stop: arresto immediato della macchina (emergenza).
  • Simulator: rotate and zoom the 3D path to inspect each segment.
    Simulator: ruota e ingrandisci il percorso 3D per ispezionare ogni segmento.

Ctrl + Delete
Ctrl + I
Ctrl + +
Ctrl + -
Ctrl + R
Ctrl + M
Ctrl + G

  • .png, .jpg, .jpeg
  • .svg
  • .dxf
  • .gcode, .nc


Alt + A
Alt + S
Alt + D

  • POLYLINE(PV['p_<n>'])


shift + e
shift +c
shift + u
shift + r
shift + a
shift + d
shift + q

  • // Create a 6-sided hexagon of radius 100
    POLYGON(10, 50, 50, 30)

  • // Render “Hello” at position (100, 200) with font size 48
    TEXT('roboto_b', 48, 30, 30, 'hello')

var t = TEXT('roboto_b', 36, 25, 35, 'hi')
var circ = POLYGON(32, 40, 40, 40)
difference(circ, t)

translate(dx, dy)
rotate(angle)
scale(sx, sy)
mirror(axis)
skew(axis, angle)
offset(dist)
tab(size, n)

union(pathA, pathB, ...)
intersection(pathA, pathB)
difference(pathA, pathB)
xor(pathA, pathB)
center(pathA, pathB)

// Draw two overlapping circles, then subtract one from the other
var a = POLYGON(20, 30, 30, 20)
var b = POLYGON(8, 50, 50, 20)
union(a,b)



// Import a 200 (preserve aspect ratio) image at position (50, 50)
IMAGE(size=200, gamma=0, x=50, y=50, rot=0, flip='')
  • size:
  • gamma:
  • x, y:
  • rot:
  • flip:

img.vector(level)
img.dit(method)
img.half(method)
img.cutter()

IMAGE(size=100, gamma=0, x=10, y=10, rot=0, flip='').dit()

// Trace at 40 threshold
IMAGE(size=100, gamma=0, x=10, y=10, rot=0, flip='').vector(40)

  • TRACE(img, threshold):

// Full workflow
IMAGE(200, 0, 0, 0, '').vector(40).gcode()



G-code Workflow
Flusso G-code

G-code Generation Modal
Finestra Generazione G-code

Vector Example
Esempio Vettoriale

Raster Example
Esempio Raster

Parameter Configuration
Configurazione Parametri

Create vs Download
Create vs Download

GRBL Interface & Simulator
Interfaccia GRBL e Simulatore

Interface Overview
Panoramica Interfaccia




Jog Controls & Shortcuts
Controlli Jog e Scorciatoie

Shortcut
Scorciatoia
Action
Azione
Example
Esempio
Ctrl + ↑ ↓ ← → Ctrl + ↑
Ctrl + Shift + ↑ ↓ ← → Ctrl + Shift + →
Ctrl + PageUp / PageDown Ctrl + PageDown
Ctrl + Shift + PageUp / PageDown Ctrl + Shift + PageUp
Shift + F / G / R Shift + G
Shift + S / D / X Shift + D
Shift + Z / A / Q Shift + A
Ctrl + Alt + F + [0–9] Ctrl + Alt + F + 5
Ctrl + Alt + D + [0–9] Ctrl + Alt + D + 2
Ctrl + Alt + X + [0–9] Ctrl + Alt + X + 8 → 800
Ctrl + Alt + Z + [0–9] Ctrl + Alt + Z + 4 → 400
Ctrl + Esc Ctrl + Esc

This is a brief overview. For detailed documentation, please visit the Wiki section of the repository.

The most direct way to try the app is by clicking the DEMO button or accessing the GitHub Live version. However, for the best experience, we recommend installing it as a Progressive Web App (PWA) on your device.
Il modo più diretto per provare l’app è cliccando sul pulsante DEMO oppure accedendo alla versione Live ospitata su GitHub. Tuttavia, per un’esperienza ottimale, si consiglia di installarla come Progressive Web App (PWA) sul proprio dispositivo.

Source Code

The project is open source and available on GitHub. Take a look, suggest improvements or contribute!

Go to Repository

Contacts

contacts

HobbyLASER is not affiliated with any specific hardware

For support requests, feature suggestions, please use the GitHub Discussions

Only if you’ve found a software bug, open a bug report in the GitHub Issues