The New Cartridge Is JavaScript: Nova64 Has Arrived in RetroArch

A fantasy console built with the creative vocabulary of Three.js can now run beside the machines that inspired it.

RetroArch is one of the great preservation projects in computing.

It gives old consoles, arcade boards, handhelds, and computers a shared place to keep running long after their original hardware begins disappearing.

Nova64 asks a slightly different question:

What if RetroArch could also run cartridges for a machine that never existed?

Nova64 is a JavaScript fantasy console inspired by the first generation of consumer 3D: the Nintendo 64, PlayStation, arcade hardware, demoscene productions, early browser experiments, and the strange optimism of multimedia software in the late 1990s.

Its cartridges can begin in the browser with a Three.js-style creative API and then travel into a native RetroArch core.

That is the part I believe is genuinely special.

A web developer can create a 3D game with JavaScript, cameras, meshes, lights, particles, sound, post-processing, and gamepad input, package it as a Nova64 cartridge, and run it through RetroArch beside the systems that inspired it.

The cartridge is new.

The ritual feels familiar.

This Is Not an N64 Emulator

Nova64 is not emulating a Nintendo 64, PlayStation, or another historical machine.

It is a new fantasy platform with its own runtime, cartridge format, capabilities, constraints, and personality.

On the web, Nova64 can translate its shared API into Three.js or Babylon.js. Inside RetroArch, it does something more unusual: the core embeds QuickJS to execute the cartridge’s JavaScript, while native Nova64 systems handle graphics, audio, input, storage, packaging, and the RetroArch lifecycle.

There is no hidden Chromium window inside the core. Three.js itself is not being smuggled into RetroArch.

Instead, Nova64 preserves the expressive ideas that make modern JavaScript graphics enjoyable and translates them into a compact native runtime.

That distinction matters.

The creator works with familiar concepts:

  • Scenes and meshes
  • Perspective and orthographic cameras
  • Ambient, directional, and point lights
  • Materials, textures, emissive color, opacity, roughness, and metalness
  • Instanced geometry
  • Particles and procedural noise
  • Fog, skyboxes, shadows, and render targets
  • Bloom, CRT distortion, pixelation, vignette, chromatic aberration, color grading, film grain, and other post-processing effects
  • Gamepads, keyboards, mouse input, touch input, and rumble
  • Sound effects, music, named audio channels, echo, stereo panning, and positional sound
  • Persistent storage, save states, and packaged assets

But the resulting cartridge is not trapped in a web page.

A Three.js-Inspired Cartridge

If you have worked with Three.js, the shape of a Nova64 cartridge should feel immediately understandable.

You create objects, position them, configure a camera, add lighting, enable effects, and update the world every frame.

const {
  createCube,
  setPosition,
  setRotation,
  setMeshEmissive,
} = nova64.scene;

const {
  setCameraPosition,
  setCameraTarget,
  setCameraFOV,
} = nova64.camera;

const {
  setAmbientLight,
  setLightDirection,
  setFog,
} = nova64.light;

const { enableBloom } = nova64.fx;

let artifact;
let time = 0;

export function init() {
  artifact = createCube(1.5, 0x3355ff, [0, 0, 0]);
  setPosition(artifact, 0, 0, -4);
  setMeshEmissive(artifact, 0x00ffff, 1.2);

  setCameraPosition(0, 1.5, 5);
  setCameraTarget(0, 0, -4);
  setCameraFOV(60);

  setAmbientLight(0x222244, 1.2);
  setLightDirection(-0.4, -1, -0.3);
  setFog(0x050018, 8, 60);
  enableBloom(1.0, 0.4, 0.4);
}

export function update(dt) {
  time += dt;
  setRotation(artifact, time * 0.4, time * 0.8, 0);
}

export function draw() {}

That same cartridge lifecycle follows the game into RetroArch:

init() prepares the world.

update(dt) advances it.

draw() renders cartridge-controlled overlays and presentation.

This is not a promise that every arbitrary Three.js package will run unchanged. Nova64 provides a deliberate, portable API rather than exposing the internals of one renderer.

That boundary is the reason a cartridge can travel.

RetroArch Is More Than a Deployment Target

RetroArch gives Nova64 something the browser cannot completely reproduce: the feeling of being a console.

You choose the Nova64 core.

You select a cartridge.

The screen changes.

The controller becomes active.

The cartridge boots.

That sequence has emotional weight. It connects a new creative runtime to decades of console and arcade history.

It also provides real platform services. RetroArch owns the application lifecycle, controller polling, video presentation, audio callbacks, save directories, save states, and frontend integration. Nova64 can concentrate on being a small expressive machine inside that environment.

The result is not simply a web game wrapped in an emulator-shaped window.

It is a JavaScript cartridge running through a native libretro core.

What Can the RetroArch Core Actually Do?

The Nova64 core has grown far beyond its earliest rotating-cube experiments.

Native 3D Rendering

The active hardware renderer uses OpenGL ES 3.1 through a RetroArch-owned graphics context. It supports cubes, planes, UV spheres, cones, capsules, cylinders, custom mesh geometry, scene hierarchies, instanced meshes, perspective and orthographic cameras, fog, skyboxes, render targets, ambient and directional light, point lights, and directional shadow maps.

Materials can use textures, normal maps, emissive color, transparency, UV transforms, roughness, metalness, and opaque, additive, or multiply blending.

This is enough to build racing games, dungeon crawlers, shooters, generative spaces, strange simulations, audiovisual demos, and experiences that do not fit neatly into a genre.

F-Zero Nova 3D uses the shared Nova64 API for a neon anti-gravity racing cartridge.

Modern Effects With Retro Intentions

Nova64 is nostalgic, but it is not limited to reproducing old hardware defects literally.

The RetroArch post-processing pipeline includes CRT curvature, vignette, pixelation, bloom, chromatic aberration, posterization, color grading, exposure, saturation, temperature, vibrance, sharpening, and film grain.

The hardware path includes an HDR render target and guarded multi-level bloom, with fallbacks when a driver cannot support the preferred format.

Creators can use modern rendering techniques to produce an emotional memory of old hardware instead of only imitating its specification sheet.

2D Graphics and Interface Composition

The core also includes a 640 by 360 software framebuffer and a 2D overlay compositor. Cartridges can draw pixels, lines, shapes, gradients, sprites, bitmap fonts, text effects, clipping regions, transformed cameras, palettes, tilemaps, minimaps, particles, and Canvas-style interface elements over the 3D scene.

The software path provides a fallback when hardware 3D is unavailable, while the compositor allows a native 3D world to retain the crisp interface language of a fantasy console.

Nova64 combines a native 3D world with a cartridge-controlled score display, health interface, and retro presentation.

Audio, Input, and Physical Feedback

A cartridge can generate procedural sound effects or load PCM and WAV assets. It can stream music, control named channels, change pitch and volume, apply echo, position sound in 3D, and pan audio across the stereo field.

Input includes four gamepad ports, keyboard controls, mouse movement and buttons, pointer or touch coordinates, and controller rumble.

That makes Nova64 useful for more than visual demonstrations. It can support complete games with menus, multiplayer input, persistent progress, physical feedback, and structured audio.

Storage, Packages, and Save States

Nova64 supports plain JavaScript files during development and .nova cartridges for distribution.

A .nova file is a zip-style package containing a manifest, an entry module, optional helper modules, images, fonts, audio, and other declared assets. Relative ES module imports continue to work inside the staged package.

Cartridges can save JSON data through RetroArch’s save directory, use compressed storage, and participate in versioned save states. The core also exposes cartridge memory through peek and poke for RetroAchievements-style integration.

The important idea is that the cartridge becomes a real object again.

It is a file you can archive, copy, inspect, share, load, and preserve.

The Cartridge Can Travel

Nova64 is designed around one shared creative API with several destinations.

In the browser, Three.js and Babylon.js provide modern web rendering.

In the native Godot host, QuickJS runs the cartridge while Godot provides native rendering and platform services.

In RetroArch, QuickJS runs the cartridge while the Nova64 libretro core provides its own compact graphics, sound, input, storage, and packaging systems.

The implementation changes.

The creative vocabulary survives.

This is where Nova64 becomes more than a JavaScript library.

It becomes a portable media runtime.

Why This Is a Game Changer for Web Creators

JavaScript developers already have access to one of the largest creative communities in software.

They know modules, browser tools, live reload, package managers, editors, and web graphics. Many of them can create remarkable experiences with Three.js but have never considered writing a libretro core, embedding a scripting engine, building a native renderer, or packaging something as a console cartridge.

They should not need to.

Nova64 creates a bridge between those worlds.

A creator can begin with the language and mental model they already understand. The runtime handles the difficult translation between web rendering, native hosts, and RetroArch.

That changes what a fantasy console can be.

It no longer has to be restricted to a tiny custom language or a browser-only sandbox. It can offer a deliberately constrained creative API while still drawing from the enormous expressive range of modern JavaScript graphics.

The limitation becomes a frame for creativity rather than a wall around it.

Built for Carts That Should Have Existed

At Starcade9, this matters for reasons beyond engineering.

Starcade9 is an arcade and archive for games that existed, games that almost existed, and games that should have existed.

Nova64 gives those impossible games a machine.

A JavaScript cartridge can become a dungeon crawler, a racing game, an audiovisual demo, or something without an established name.

Maybe somebody creates a lost 1998 arcade racer that never made it out of a fictional test location.

Maybe somebody builds a five-minute demoscene cartridge designed to run once at midnight.

Maybe a visual artist creates an interactive album.

Maybe a teenager makes a game on a laptop and later sees the same cartridge running through RetroArch on a Raspberry Pi connected to a CRT.

Maybe one of these cartridges eventually becomes a coin-operated cabinet on the Santa Cruz Beach Boardwalk.

That is the future Starcade9 wants to archive.

Not only the history we received.

The history we can still invent.

Where It Runs

As of Nova64 v0.5.3, prebuilt RetroArch cores are published for:

  • Windows x86-64
  • macOS universal, covering Intel and Apple silicon
  • Linux x86-64
  • Linux ARM64, including 64-bit Raspberry Pi systems
  • Linux ARMHF for older 32-bit ARM systems
  • Android ARM64, ARMv7, and x86-64
  • iOS ARM64
  • tvOS ARM64

Hardware and driver validation is continuing across the matrix. OpenGL ES 3.1 is the active 3D backend, software 2D remains available as a fallback, and Vulkan support is staged but not yet implemented.

I would rather describe that boundary honestly than pretend every driver and platform is already identical.

Portability becomes trustworthy through testing, not declarations.

Testing the Fantasy

The RetroArch core is backed by a large conformance suite covering cartridge lifecycle, framebuffer output, 3D commands, materials, textures, shadows, audio, input, storage, packaging, effects, particles, utilities, and Canvas-style UI features.

The test harness can compare framebuffer and audio checksums, record deterministic renderer commands, capture software and GLES output, inject input, and run cartridges without opening the full RetroArch frontend.

Nova64 also compares browser and RetroArch captures to measure visual parity.

That work is not glamorous, but it is what allows a neon track, a dungeon wall, a sprite, a camera, or a bloom effect to remain recognizable as a cartridge moves between renderers.

The fantasy is that one cartridge can run everywhere.

The tests keep the fantasy honest.

Load the Core. Make Something Impossible.

The Nova64 RetroArch core is available now through the project’s GitHub releases.

Download the binary for your platform, install it in RetroArch’s core directory, and load a JavaScript or .nova cartridge as content.

If you are a web developer, creative coder, generative artist, demoscene programmer, emulator enthusiast, or person who still thinks loading a cartridge should feel slightly magical, I want you to try it.

Build something small.

Build something strange.

Build a game that appears to have fallen out of an alternate 1999.

Then put it in the archive.

Starcade9 will keep a cabinet open for it.

References and Further Exploration