Browser-based Laser Harp instrument for interactive musical performance and experimentation
laserharp is a lightweight web server delivering a browser-based laser harp instrument interface. It serves static assets including an interactive HTML5 canvas UI that simulates a laser harp, enabling users to play beams with mouse, touch, or keyboard and experiment with musical scales, root keys, waveforms, and effects directly in the browser.
- Static file server serving the laser harp web interface on port 4049
- Interactive UI rendered in
public/index.htmlwith:- Bottom neon HUD featuring:
- Waveform selector buttons
- Scale selector buttons
- Root key selector
- Reverb and delay mix sliders
- Canvas-based laser harp visualization and interaction
- Bottom key hints for user guidance
- Bottom neon HUD featuring:
- Left-click or touch hold for mouse/touch beam playing
- Keyboard beam input with
a s d f g h j k l ; q w e r t - Right-click modulation while holding left click for tremolo, detune, brighter filtering, and boosted ambience
- Settings persistence for scale, key, waveform, reverb, and delay
- Custom fonts and styling for a sleek dark-themed digital instrument look
- Audio playback support for multiple audio formats (wav, mp3, ogg) as indicated by MIME types
- Dockerized deployment for easy container-based hosting
- Single HTTP server implemented in
server.jsserving all static assets securely with directory traversal protection - VST3 plugin in
plugin/built with JUCE + CMake for Windows and Linux
A native VST3 plugin source tree lives in plugin/ and is built with JUCE + CMake. See plugin/README.md for full build instructions. The plugin provides 13 string voices, mouse-beam and MIDI note triggering, root-key scale snapping, waveform selection, filter, reverb, delay, and right-click modulation.
| Technology | Role |
|---|---|
| Node.js | HTTP static file server |
| JavaScript | Server-side scripting |
| HTML5 | User interface markup |
| CSS3 | UI styling and layout |
| Docker | Containerization and deployment |
| HTTP | Protocol for serving assets |
The project consists of a single Node.js HTTP server (server.js) that serves static files from the public/ directory. The client-side UI is a single-page application contained in public/index.html with embedded CSS styles. The server listens on port 4049 and handles requests by mapping URLs to files within the public/ folder, enforcing security by preventing directory traversal. The Dockerfile builds a lightweight Node.js Alpine Linux container image, exposing port 4049, which is mapped to port 4051 on the host via docker-compose.yml.
- Node.js 20.x (tested with Node 20-alpine base image)
- Docker (for containerized deployment)
- Docker Compose (for multi-service orchestration, though only one service here)
-
Clone the repository:
git clone <repository-url> cd laserharp
-
Install dependencies (none explicitly listed, so no
npm installneeded) -
To run locally without Docker, use the start script:
npm start
Run the server directly with Node.js:
npm startThis starts the HTTP server on http://localhost:4049. Hold left click or touch a beam to play with the pointer, or use the keyboard row shown at the bottom of the instrument.
Build and run the Docker container:
docker build -t laserharp .
docker run -p 4051:4049 --name laserharp --restart unless-stopped laserharpOr use Docker Compose:
docker-compose up -dThis runs the container named laserharp exposing port 4051 on the host mapped to 4049 in the container.
- Build image:
docker build -t laserharp . - Run container:
docker run -p 4051:4049 --name laserharp --restart unless-stopped laserharp
- Using Docker Compose:
docker-compose up -d
- Stop container:
docker-compose down
This project does not expose a REST API or backend routes beyond static file serving. The HTTP server serves files from the public/ directory:
/→ servesindex.html/[filename]→ serves static assets such as CSS, JS, images, audio files
| Variable | Description | Required |
|---|---|---|
| (none) | No environment variables used | No |
Note: The server port is hardcoded to 4049 in server.js. To change it, modify the PORT constant in the source code.