This content originally appeared on DEV Community and was authored by Pavel
(This is Part 2 of my journey. If you haven't read it yet, start with Part 1 here!)
Last time, I performed a small miracle: I built, trained, and got a GPT model to generate text using only pure JavaScript. I went through the trenches of debugging gradients, battled NaN
values, and ultimately ended up with a working model. It was proof that the fundamental concepts of AI are accessible right in the browser.
But a question lingered in the back of my mind: "What if...?"
- What if I needed performance comparable to a native application?
- What if I wanted the strict typing and safety that JavaScript can't offer?
- What if I wanted to turn this educational project into a true high-performance experimental testbed?
The answer to all these questions was the same: Rust and WebAssembly.
Chapter 1: The Birth of the Second Engine — RustyGradients
Before bringing anything into WebAssembly, I needed the engine itself. Simply porting slmnet.js
to Rust felt uninspired. Instead, I decided to build a complete, strictly-typed, and modular deep learning framework from scratch, heavily inspired by PyTorch.
And so, RustyGradients was born.
This is not just a port. It's a different beast entirely, built on the principles of Rust:
- Safety and Reliability: No more
undefined is not a function
. The Rust compiler became my best friend, catching errors long before they could ever reach the browser. - Performance: Rust compiles down to blazingly fast machine code. All those endless loops in matrix multiplications and backpropagation now execute at near-native speed.
- Robust Architecture: A
Module
trait (similar totorch.nn.Module
) and a clear separation of operations (ops
), optimizers (optim
), and layers (nn
) makes the code clean and extensible.
Building
RustyGradients
was an adventure in itself, but the goal was always clear: to forge a powerful engine ready to be installed in my "race car."
Chapter 2: The Bridge to the Future — Integration via WebAssembly
WebAssembly (WASM) is the magic that allows code written in languages like Rust, C++, or Go to run right in the browser. It's not a replacement for JavaScript, but its perfect companion: JS handles the UI, while WASM crunches the heavy numbers.
Using the wasm-pack
tool, I compiled the entire RustyGradients
framework and the GPT model written with it into a single, compact .wasm
file.
For JavaScript, the complexity of the Rust code was hidden behind a simple and elegant API:
// JS code in index.html
import init, { WasmGptTrainer } from './pkg/rusty_gradients.js';
// ... initialization ...
// I can create an instance of the entire Rust model in one line!
let trainer = new WasmGptTrainer(config...);
// A single training step is just one function call,
// all the magic happens inside WASM
const loss = trainer.train_step(x_batch, y_batch);
// Text generation is also a single call
const generated_ids = trainer.generate(prompt_ids, 300, 0.8, 10);
All the math, all the tensors, all the gradients now live and breathe inside the lightning-fast WASM module.
Chapter 3: The Ultimate Testbed — Choice and Persistence
Just replacing the engine wasn't interesting enough. I wanted to create a platform where I could compare these two worlds. And frankly, I was tired of losing my trained model every time I refreshed the page.
This led to the final version of slmnetGPT, which now includes:
1. The Engine Switch:
The UI now features a choice: run the model on pure slmnet.js
or on RustyGradients (WASM)
. This allows for a real-time comparison of the training speed and performance of the two approaches.
<!-- Replace with a screenshot of your UI -->
2. Long-Term Memory with IndexedDB:
localStorage
was fine for a start, but it's too small and slow. I integrated IndexedDB, a full-fledged NoSQL database in the browser. Now you can:
- Save the state of a trained model after a long session.
- Load it at any time, even after a browser restart.
- Delete the saved weights to start fresh.
Crucially, the models for the JS and WASM engines are saved separately. You can train both and switch between their "brains."
3. Localization:
As a final touch, I added a simple language switcher (RU/EN) to make the testbed even more user-friendly.
Conclusion: Two Worlds, One Mission
This project grew from a simple "What if?" into a comprehensive "Yes, and here's how." It has become a living demonstration of a powerful synergy:
- JavaScript remains the king of the user interface. Its flexibility and simplicity make building interactive applications a joy.
- Rust + WebAssembly is the turbocharger for your web app. They take over the heavy lifting, providing a level of performance that was once only a dream in the browser.
Now, slmnetGPT
is more than just a model. It's a laboratory in your browser.
Come in, experiment, and compare:
- The JavaScript version: https://github.com/Xzdes/slmnetGPT
- The Rust engine: https://github.com/Xzdes/RustyGradients
Run the training on both engines. Save the result. See how the Rust-trained model generates text. Feel the difference.
This content originally appeared on DEV Community and was authored by Pavel

Pavel | Sciencx (2025-08-26T09:02:31+00:00) I Supercharged My Browser GPT with Rust and WebAssembly: The Journey to a Dual-Engine AI. Retrieved from https://www.scien.cx/2025/08/26/i-supercharged-my-browser-gpt-with-rust-and-webassembly-the-journey-to-a-dual-engine-ai/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.