diff --git a/.gitignore b/.gitignore
index 6c7bc2d1b0388931262f5dfc95b14cb906f8b0dc..98b51824253cabbda2befd9103c5d5123b01c897 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@ Cargo.lock
 /frontends/*/target
 
 /src/gen/build.rs
+/src/gen/_build.rs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fbb835a6f6c8cd5d7bd4fa2f29d83f76b4867065..7ee5b5a22c1ee39b1263dda8ae75e0d2faf83ecf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
-*
+* Support for WASM engine version printing
 
 ### Changed
 
diff --git a/Cargo.toml b/Cargo.toml
index b8a44a36ce329ce3e178a4b401f796d5c3d93722..65a09a8928d7cd4ff834287642e7e77677890399 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -25,6 +25,7 @@ wasm-bindgen = { version = "0.2", optional = true }
 [build-dependencies]
 chrono = "0.4"
 regex = "1"
+built = "0.5"
 
 [profile.release]
 debug = false
diff --git a/build.rs b/build.rs
index 32323375a38753546bba42376ca57c5343fdb559..bf1b12ca383a82cf8863d12f4055e2ce822e8700 100644
--- a/build.rs
+++ b/build.rs
@@ -1,28 +1,30 @@
 #![allow(clippy::uninlined_format_args)]
 
-/// Build script (https://doc.rust-lang.org/cargo/reference/build-scripts.html)
-/// This script is executed as the first step in the compilation process.
-/// Here we export metadata constants to a `constants/generated.rs` file which is then
-/// imported and used by the remaining crate.
-///
-/// # Examples
-///
-/// In C you can use the preprocessor macro `__DATE__` to save the compilation date like:
-///
-/// ```c
-/// #define COMPILATION_DATE __DATE__
-/// ```
-///
-/// Rust does not have such preprocessor macros, so we use this script and do:
-///
-/// ```rust
-/// let now_utc = chrono::Utc::now();
-/// write_str_constant(
-///     &mut file,
-///     "COMPILATION_DATE",
-///     &format!("{}", now_utc.format("%b %d %Y")),
-/// );
-/// ```
+//! Build script (https://doc.rust-lang.org/cargo/reference/build-scripts.html)
+//! This script is executed as the first step in the compilation process.
+//! Here we export metadata constants to a `constants/generated.rs` file which is then
+//! imported and used by the remaining crate.
+//!
+//! # Examples
+//!
+//! In C you can use the preprocessor macro `__DATE__` to save the compilation date like:
+//!
+//! ```c
+//! #define COMPILATION_DATE __DATE__
+//! ```
+//!
+//! Rust does not have such preprocessor macros, so we use this script and do:
+//!
+//! ```rust
+//! let now_utc = chrono::Utc::now();
+//! write_str_constant(
+//!     &mut file,
+//!     "COMPILATION_DATE",
+//!     &format!("{}", now_utc.format("%b %d %Y")),
+//! );
+//! ```
+
+use built::{write_built_file_with_opts, Options};
 use chrono::Utc;
 use regex::Regex;
 use std::fs::{File, OpenOptions};
@@ -32,7 +34,7 @@ use std::process::Command;
 use std::{env, str};
 
 const BUILD_OUT_FILE: &str = "build.rs";
-const SOURCE_DIR: &str = "./src/gen";
+const GEN_DIR: &str = "./src/gen";
 
 fn main() {
     // in case we're running under docs.rs then we must return the control
@@ -44,7 +46,7 @@ fn main() {
 
     // opens the target destination file panicking with a proper message in
     // case it was not possible to open it (eg: directory inexistent)
-    let dest_path = Path::new(SOURCE_DIR).join(Path::new(BUILD_OUT_FILE));
+    let dest_path = Path::new(GEN_DIR).join(Path::new(BUILD_OUT_FILE));
     let mut file = OpenOptions::new()
         .truncate(true)
         .write(true)
@@ -52,11 +54,8 @@ fn main() {
         .open(dest_path)
         .unwrap_or_else(|_| panic!("Can't open '{}'", BUILD_OUT_FILE));
 
-    let module_doc_string = "//! Global constants, such as compiler version used, features, platform information and others.\n";
-    writeln!(file, "{}", module_doc_string).unwrap();
-
-    let generated_annotation = "// @generated\n";
-    writeln!(file, "{}", generated_annotation).unwrap();
+    writeln!(file, "{}", "//! Global constants, such as compiler version used, features, platform information and others.\n").unwrap();
+    writeln!(file, "{}", "// @generated\n").unwrap();
 
     let now_utc = Utc::now();
     write_str_constant(
@@ -152,6 +151,19 @@ fn main() {
         "PLATFORM_CPU_BITS_INT",
         std::mem::size_of::<usize>() * 8,
     );
+
+    let mut options = Options::default();
+    options.set_cfg(false);
+    options.set_ci(false);
+    options.set_compiler(false);
+    options.set_env(false);
+    options.set_dependencies(true);
+    options.set_features(true);
+
+    let manifest_path = env::var("CARGO_MANIFEST_DIR").unwrap();
+    let built_path = Path::new(GEN_DIR).join(Path::new("_build.rs"));
+
+    write_built_file_with_opts(&options, manifest_path.as_ref(), &built_path).unwrap();
 }
 
 fn write_constant<T>(file: &mut File, key: &str, val: T)
diff --git a/frontends/web/ts/gb.ts b/frontends/web/ts/gb.ts
index 02bb2589dab511c0315c10388444a83bf23d0a16..4e82177b281dc06b9072a98be8698a230e2c3ee4 100644
--- a/frontends/web/ts/gb.ts
+++ b/frontends/web/ts/gb.ts
@@ -547,6 +547,11 @@ export class GameboyEmulator extends EmulatorBase implements Emulator {
         };
     }
 
+    get wasmEngine(): string | null {
+        if (!this.gameBoy) return null;
+        return this.gameBoy.get_wasm_engine_ws();
+    }
+
     get framerate(): number {
         return this.fps;
     }
diff --git a/src/gb.rs b/src/gb.rs
index f78ff75fc82a66905b601237ed687a42cb9e29fa..b6394104d8cb452b509bce7d6b456637ec2b68a5 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -14,7 +14,10 @@ use crate::{
 use wasm_bindgen::prelude::*;
 
 #[cfg(feature = "wasm")]
-use crate::ppu::{Palette, Pixel};
+use crate::{
+    gen::dependencies_map,
+    ppu::{Palette, Pixel},
+};
 
 #[cfg(feature = "wasm")]
 use std::{
@@ -319,6 +322,17 @@ impl GameBoy {
         self.ppu().set_palette_colors(&palette);
     }
 
+    pub fn get_wasm_engine_ws(&self) -> String {
+        let dependencies = dependencies_map();
+        if !dependencies.contains_key("wasm-bindgen") {
+            return String::from("-");
+        }
+        String::from(format!(
+            "wasm-bindgen/{}",
+            *dependencies.get("wasm-bindgen").unwrap()
+        ))
+    }
+
     fn js_to_pixel(value: &JsValue) -> Pixel {
         value
             .as_string()
diff --git a/src/gen/mock.rs b/src/gen/mock.rs
index 5a9b8dde35c5166663a2c64ced1e6f73b6ac5f54..4c9a6c39938e259c1e76f990a0364cbf37c6617d 100644
--- a/src/gen/mock.rs
+++ b/src/gen/mock.rs
@@ -14,3 +14,8 @@ pub const MAKEFLAGS: &str = "-";
 pub const FEATURES: [&str; 1] = ["cpu"];
 pub const PLATFORM_CPU_BITS: &str = "64";
 pub const PLATFORM_CPU_BITS_INT: usize = 64;
+
+pub const FEATURES: [&str; 0] = [];
+pub const FEATURES_STR: &str = r"";
+pub const DEPENDENCIES: [(&str, &str); 0] = [];
+pub const DEPENDENCIES_STR: &str = r"";
diff --git a/src/gen/mod.rs b/src/gen/mod.rs
index 427c7d62d5882599a3c821dcc2d5fdab4a7fe9db..f65c55cec15b65ccc667b6fc08ac6b13da510fb5 100644
--- a/src/gen/mod.rs
+++ b/src/gen/mod.rs
@@ -1,5 +1,7 @@
 //! Constants that define the current build and execution environment.
 
+use std::collections::HashMap;
+
 #[cfg(feature = "gen-mock")]
 pub mod mock;
 #[cfg(feature = "gen-mock")]
@@ -10,3 +12,11 @@ pub use self::mock::*;
 pub mod build;
 #[cfg(not(feature = "gen-mock"))]
 pub use self::build::*;
+#[cfg(not(feature = "gen-mock"))]
+pub mod _build;
+#[cfg(not(feature = "gen-mock"))]
+pub use self::_build::*;
+
+pub fn dependencies_map() -> HashMap<&'static str, &'static str> {
+    HashMap::from(DEPENDENCIES)
+}