Skip to content

Guides

How to Run DOS Games in Browser with JS-DOS v8: Complete WebAssembly Embed Guide

Embed classic MS-DOS games into your website using JS-DOS v8 and WebAssembly. Step-by-step bundle packaging, audio buffer tuning, and IndexedDB save state persistence.

3 min read
Topic
Browser emulation
Difficulty
advanced
Spoilers
None

To run classic MS-DOS games inside any modern web browser without server-side compute, embed JS-DOS v8 using its client-side WebAssembly DOSBox-X runtime paired with pre-packaged .jsdos archive bundles. JS-DOS compiles native x86 CPU emulation, Sound Blaster 16 audio synthesis, and VGA 320x200 graphical rendering into clean client-side WebAssembly that executes at full 60 FPS without user plugins.

JS-DOS v8 Architecture vs. Traditional Browser Emulators

Earlier browser DOS solutions relied on monolithic JavaScript conversions that stuttered during audio playback. Version 8 decouples the core emulator engine from the frontend presentation layer:

Feature JS-DOS v8 (Current) Legacy JS-DOS v6 / v7 EmulatorJS DOS Core
Underlying Engine DOSBox-X (Modern fork) DOSBox 0.74 (Frozen) DOSBox SVN Libretro Core
Audio Pipeline Web Audio API + AudioWorklet ScriptProcessorNode (High Latency) WebAssembly SharedArrayBuffer
Save State Support Native IndexedDB auto-sync Manual file download Browser local storage cache
Graphics Backend WebGL 2.0 with CRT shaders Software 2D Canvas WebGL RetroArch shaders
Bundle Format Single .jsdos zip archive Loose files or flat tar ROM + Config ZIP

Minimal HTML5 & JavaScript Implementation

Save the following production template as index.html. It pulls the official JS-DOS v8 distribution and boots a local bundle:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Embedded DOS Player</title>
    <!-- JS-DOS v8 Styling and Core Scripts -->
    <link rel="stylesheet" href="https://v8.js-dos.com/latest/js-dos.css">
    <script src="https://v8.js-dos.com/latest/js-dos.js"></script>
    <style>
        #dos-container {
            width: 640px;
            height: 400px;
            background: #000;
            margin: 20px auto;
            position: relative;
        }
    </style>
</head>
<body>
    <div id="dos-container"></div>

    <script>
        // Configure WebAssembly binary asset paths
        emulators.pathPrefix = "https://v8.js-dos.com/latest/emulators/";

        // Initialize player on the target container
        Dos(document.getElementById("dos-container"), {
            backend: "dosboxX", // Options: 'dosbox' (fast) or 'dosboxX' (accurate)
            autolock: true,     // Automatically capture mouse pointer for 3D shooters
            theme: "dark",
        }).then((ci) => {
            // Load your packaged game bundle
            return ci.load("game.jsdos");
        }).catch((err) => {
            console.error("DOS Boot Failure:", err);
        });
    </script>
</body>
</html>

How to Package a Production .jsdos Bundle

A .jsdos file is a standard ZIP archive renamed with the .jsdos file extension. It must contain your game executables and an optimized dosbox.conf startup script.

Directory Structure Inside the Bundle:

game.jsdos (ZIP archive)
├── dosbox.conf
└── GAME/
    ├── DOOM.EXE
    └── DOOM1.WAD

Essential dosbox.conf Tuning:

Create dosbox.conf with specific CPU and Sound Blaster settings tailored for browser execution:

[cpu]
core=dynamic
cputype=auto
cycles=max

[mixer]
rate=44100
blocksize=1024
prebuffer=20

[sblaster]
sbtype=sb16
sbbase=220
irq=7
dma=1
hdma=5
sbmixer=true

[autoexec]
mount c ./GAME
c:
DOOM.EXE

Troubleshooting: Mouse Lock, Audio Latency, and Saves

1. Fixing Sound Stutter (AudioWorklet Fallback)

If audio crackles on low-spec client machines, increase the blocksize in dosbox.conf from 1024 to 2048 and set prebuffer=40. This introduces ~20ms of audio latency but completely eliminates buffer under-runs.

2. First-Person Shooter Mouse Capture

For games like Doom, Blood, or Duke Nukem 3D, ensure your hosting page uses HTTPS. Browsers block the W3C Pointer Lock API over insecure HTTP origins.

3. Persistent Save Files (IndexedDB)

JS-DOS v8 automatically writes save-game modifications back to the browser’s local IndexedDB under /home/web_user/.jsdos/. To extract save files across sessions, utilize the Client Instance (ci) API to trigger ci.persist().

For further upstream architecture documentation, consult the JS-DOS GitHub repository and the DOSBox-X Developer Portal.