{
"$type": "site.standard.document",
"canonicalUrl": "https://afloat.boats/posts/rust-for-javascript-engineers-pt-1",
"description": "Project structure, wasm-bindgen, enums, and traits — first steps toward building Connect-4 with Rust and WASM.",
"path": "/posts/rust-for-javascript-engineers-pt-1",
"publishedAt": "2025-08-19T23:12:10.000Z",
"site": "at://did:plc:pans3xjam4khj7y54dx7gtfg/site.standard.publication/3mdqevmg6w32c",
"tags": [
"rust",
"game dev",
"WASM"
],
"textContent": "<a href=\"/connectors\" target=\"_blank\" rel=\"noopener noreferrer\">Connect Four</a> | <a href=\"https://github.com/tauseefk/connectors\" target=\"_blank\" rel=\"noopener noreferrer\">Repository</a>\n\n[Edit] After receiving some generous feedback from my friend Tim, I've made some changes to clarify confusing topics, and added another post that should make it easier for first time Rust users to get started here. If you're already familiar with Rust project structures, and have written some amount of Rust, please continue reading.\n\n---\n\nWhen I first wanted to learn Rust in 2017, I had no idea where to start. I had written some C starting back in 7th grade, however I wasn't particularly good at it. The only language I was competent at was JavaScript, and there weren't a lot of resources that bridged the gap between JavaScript and Rust.\n\nMy hope with this series is that it'll allow people familiar with JavaScript to incrementally adopt Rust.\n\nThere are a lot of similarities between the ecosystems surrounding these languages. As all the Rust code is compiled to WASM, it can open up a path for adoption into existing JavaScript project workflows, hopefully lowering the barrier of entry.\n\nThere are also a lot of differences between these languages, some of which might be out of the scope of this series. I'll add links to more information when encountering jargon that might not make the most sense to somebody unfamiliar with the Rust ecosystem just yet.\n\nIn this series I go over building a small browser based Connect-4 game, which uses Rust compiled to WebAssembly for the core gameplay mechanics and state management.\nThis is very much a follow along, as that's what I find most effective for information retention.\nHere is the accompanying repository, that I'll use for reference. It can also serve as checkpoints in case the readers find their own implementations diverge.\n\nDirectory Structure\n\nThis is the general directory structure I use for building applications with Rust and JavaScript. I've found that this works best for building the rust crates [\\[1\\]](https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html) into packages that can be directly consumed by the JavaScript projects.\n\n1.\n\nHere is the definition of Cargo workspaces from the Rust Book.\n\n> \"...you might find that the library crate continues to get bigger and you want to split your package further into multiple library crates. Cargo offers a feature called workspaces that can help manage multiple related packages that are developed in tandem.\"\n\nIt's similar in nature to a yarn workspace where different npm packages can share project dependencies.\n\n2.\n\nIt basically means that we're going to compile the connectors crate for web target into the JavaScript project's directory so it can be imported.\n\n3.\n\nIn JavaScript all non-primitives types are passed by reference, but in Rust you have to specify whether something is a reference or a value. For more details on this topic, check out this section of the Rust Book.\nWill come back to the into call at a later point, but here's what Rust by Example has to say.\n\n4.\n\nThe client side code will be the most familiar to JavaScript engineers, it's a single JavaScript file that starts an http server using node and serves the index.html.\n\nLet's look at the javascript code:\n\nRunning the code\n\nNow that the project structure is somewhat out of the way, let's trying running the code.\n\nIf you've been following along so far, open up http://localhost:8000 in your favorite browser, \"Hello, WASM!\" should be logged in the console.\n\nConnect Four\n\nAt this point we've (hopefully) established a good baseline understanding of different parts of the codebase, we can start working towards the connect four game.\n\nLet's look at the crate changes first.\n\nengine.rs\n\nThis is the module which will hold all the data structures relevant to the gameplay.\nThe most important part of connect-4 are the states of each position.\nAll three configurations \"empty\", \"red\", and \"black\" can be stored as variants of an enum. And as we need to import this enum into the entrypoint lib.rs, I'm declaring it using a pub keyword. This is necessary as data in Rust is private by default.\n\nlib.rs\n\nUsing engine.rs in the entrypoint lib.rs.\n\nNow to the significant bit. I've updated the say_hello function to declare a few variables with the let keyword and assigned enum variants.\nThe let keyword is different from JavaScript in that it by default doesn't not allow re-assignment to those variables.\n\nWhat happens on compiling the crate via the build.sh?\n\nI get a few errors, including the following:\n\nThis is the one I really care about:\n\nLet's go ahead and implement the trait for TileType.\n\nCompiles without a hitch!\nAnd the browser console now logs:\n\nTraits are Rust's way of defining shared behavior. They are more akin to composition via object extension than classical inheritence.\n\nThe trait fmt::Display requires that the function fn fmt be implemented, which gives our enum TileType the ability to define how each of its variants are to be formatted when using the format! macro.\n\nLet's try one more thing, and implement a method on our enum directly called is_empty.\n\nEnums in Rust can also have methods.\nThis allows us to check if a particular TileType variant is empty, like the following:\n\nAfter re-compiling, the console should now log four statements:\n\nRemember that this method is associated to the concrete instance of the enum, so we'd call the method on the variant instead of the enum itself.\n\nHere's the complete diff.\n\nIn the next post we're going to look into rendering the Connect-4 board as HTML.",
"title": "Rust for JavaScript Engineers - Building Connect-4"
}