<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: JC-node</title>
    <description>The latest articles on DEV Community by JC-node (@jc-node).</description>
    <link>https://dev.to/jc-node</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4092787%2Fe4703415-3874-4864-af27-ef6bb8b6bcb8.jpg</url>
      <title>DEV Community: JC-node</title>
      <link>https://dev.to/jc-node</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jc-node"/>
    <language>en</language>
    <item>
      <title>I built a browser-based live visual instrument with WebGL, Web MIDI and separate performer/audience outputs</title>
      <dc:creator>JC-node</dc:creator>
      <pubDate>Tue, 25 Aug 2026 11:59:43 +0000</pubDate>
      <link>https://dev.to/jc-node/i-built-a-browser-based-live-visual-instrument-with-webgl-web-midi-and-separate-performeraudience-26m6</link>
      <guid>https://dev.to/jc-node/i-built-a-browser-based-live-visual-instrument-with-webgl-web-midi-and-separate-performeraudience-26m6</guid>
      <description>&lt;h1&gt;
  
  
  I built a browser-based live visual instrument with WebGL, Web MIDI and separate performer/audience outputs
&lt;/h1&gt;

&lt;p&gt;For a long time I kept coming back to the same question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why can a musician perform almost everything on stage — except the visuals?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That question eventually became &lt;strong&gt;LumaDeck Web&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is a browser-based live visual instrument for DJs, VJs, musicians and performers.&lt;/p&gt;

&lt;p&gt;The idea was not to build another passive music visualizer, but something that could actually be &lt;strong&gt;played&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basic idea
&lt;/h2&gt;

&lt;p&gt;LumaDeck has three ways of working:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auto&lt;/strong&gt; — the music drives the visuals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perform&lt;/strong&gt; — the artist takes direct control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create&lt;/strong&gt; — local videos and custom GLSL shaders become part of the instrument.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is that these modes are not isolated workflows.&lt;/p&gt;

&lt;p&gt;You can let automation run, trigger a blackout or strobe manually, launch another scene with MIDI, and then immediately let the automatic system continue the show.&lt;/p&gt;

&lt;p&gt;That continuity became one of the main design goals.&lt;/p&gt;

&lt;h2&gt;
  
  
  One screen for the performer, another for the audience
&lt;/h2&gt;

&lt;p&gt;One of the architectural decisions I cared about most was separating the operator interface from the final output.&lt;/p&gt;

&lt;p&gt;The performer needs to see things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scene launchers&lt;/li&gt;
&lt;li&gt;MIDI mappings&lt;/li&gt;
&lt;li&gt;mixer controls&lt;/li&gt;
&lt;li&gt;live effects&lt;/li&gt;
&lt;li&gt;BPM and audio analysis&lt;/li&gt;
&lt;li&gt;local media&lt;/li&gt;
&lt;li&gt;shader controls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The audience should see none of that.&lt;/p&gt;

&lt;p&gt;So LumaDeck keeps a complete &lt;strong&gt;Master&lt;/strong&gt; surface for the performer while a separate browser surface outputs only the final visual composition.&lt;/p&gt;

&lt;p&gt;That changes the interface completely.&lt;/p&gt;

&lt;p&gt;The control surface can behave like an instrument instead of having to double as something presentable on the projector or LED screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ero0n5kf1vrcuf8nng6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ero0n5kf1vrcuf8nng6.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MIDI as a performance layer
&lt;/h2&gt;

&lt;p&gt;Web MIDI became a major part of the workflow.&lt;/p&gt;

&lt;p&gt;The current Web Pro surface exposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;48 scene pads&lt;/li&gt;
&lt;li&gt;19 live controls&lt;/li&gt;
&lt;li&gt;MIDI Learn&lt;/li&gt;
&lt;li&gt;physical controller mapping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was to make the visual system behave more like the hardware musicians already understand.&lt;/p&gt;

&lt;p&gt;Instead of clicking a scene with a mouse during a performance, a pad can launch it.&lt;/p&gt;

&lt;p&gt;Instead of dragging a virtual parameter, a physical fader can control it.&lt;/p&gt;

&lt;p&gt;That changes the relationship with the visuals from selecting content to actually performing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebGL and GLSL
&lt;/h2&gt;

&lt;p&gt;The visual engine runs in the browser using WebGL and GLSL.&lt;/p&gt;

&lt;p&gt;LumaDeck currently includes 48 free audio-reactive scenes, with a larger catalog available through visual packs.&lt;/p&gt;

&lt;p&gt;Artists can also load their own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;local video loops&lt;/li&gt;
&lt;li&gt;custom GLSL shaders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those assets stay local to the browser workflow rather than being uploaded to a remote media server.&lt;/p&gt;

&lt;p&gt;That was important to me creatively as well as technically.&lt;/p&gt;

&lt;p&gt;The built-in content should make the instrument useful immediately, but it should not force an artist into somebody else's visual language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why build it in the browser?
&lt;/h2&gt;

&lt;p&gt;I originally chose the browser because it removes a huge amount of friction.&lt;/p&gt;

&lt;p&gt;No heavy installation.&lt;/p&gt;

&lt;p&gt;Immediate access.&lt;/p&gt;

&lt;p&gt;A natural way to separate control and audience surfaces.&lt;/p&gt;

&lt;p&gt;But I also wanted to know whether a browser-based visual instrument could stay stable during genuinely long sessions.&lt;/p&gt;

&lt;p&gt;During development I left LumaDeck running continuously on the same machine for &lt;strong&gt;more than nine days&lt;/strong&gt; as a real-world soak test.&lt;/p&gt;

&lt;p&gt;I eventually stopped the test manually.&lt;/p&gt;

&lt;p&gt;The application had not crashed.&lt;/p&gt;

&lt;p&gt;Obviously that does not mean every browser, GPU, driver and operating-system combination will behave identically.&lt;/p&gt;

&lt;p&gt;But it changed my own view of what a browser-based performance system can realistically do.&lt;/p&gt;

&lt;p&gt;For LumaDeck, the browser is not being used as a convenient wrapper for a webpage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The browser is the runtime of the instrument.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I think it fits
&lt;/h2&gt;

&lt;p&gt;I am not trying to reproduce Resolume or TouchDesigner inside a browser.&lt;/p&gt;

&lt;p&gt;Those are extremely capable professional environments.&lt;/p&gt;

&lt;p&gt;The space I was interested in is somewhere between:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“press play on a music visualizer”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“become a specialist visual programmer before you can put something meaningful on a screen.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wanted someone to be able to open the instrument, get useful visuals immediately, and then progressively move into MIDI, custom media and GLSL if they want more control.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would genuinely like feedback on
&lt;/h2&gt;

&lt;p&gt;LumaDeck Web is live now, and the free version can be used without creating an account:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://lumadeck.app/" rel="noopener noreferrer"&gt;https://lumadeck.app/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I am especially interested in feedback from people working with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WebGL&lt;/li&gt;
&lt;li&gt;Web MIDI&lt;/li&gt;
&lt;li&gt;browser performance&lt;/li&gt;
&lt;li&gt;realtime graphics&lt;/li&gt;
&lt;li&gt;creative coding&lt;/li&gt;
&lt;li&gt;live audiovisual systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the questions I keep thinking about is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you were using a browser as a real performance instrument, where would you want the boundary between automatic behaviour and manual control to sit?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That transition between automation and direct human intervention has been one of the hardest — and most interesting — parts of building LumaDeck.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webgl</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
