diff --git a/Cargo.toml b/Cargo.toml
index 0322342..754b68e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -221,8 +221,9 @@ members = [
"crates/modules/gioser/gioser-palette",
"crates/modules/gioser/gioser-shaders",
"crates/modules/gioser/gioser-canvas-web",
+ "crates/modules/gioser/gioser-graph-web",
- # ============================================================
+ # ==========================================================
# modules/fana/ — Writer DAG editor (absorbe pluma)
# ============================================================
"crates/modules/fana/fana-core",
diff --git a/crates/modules/gioser/gioser-graph-web/Cargo.toml b/crates/modules/gioser/gioser-graph-web/Cargo.toml
new file mode 100644
index 0000000..ae905f6
--- /dev/null
+++ b/crates/modules/gioser/gioser-graph-web/Cargo.toml
@@ -0,0 +1,37 @@
+[package]
+name = "gioser-graph-web"
+version.workspace = true
+edition.workspace = true
+license.workspace = true
+authors.workspace = true
+publish.workspace = true
+
+[dependencies]
+wasm-bindgen.workspace = true
+wasm-bindgen-futures.workspace = true
+js-sys.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+
+[dependencies.web-sys]
+workspace = true
+features = [
+ "Window",
+ "Document",
+ "Element",
+ "HtmlElement",
+ "SvgElement",
+ "SvgSvgElement",
+ "SvgCircleElement",
+ "SvgLineElement",
+ "SvgTextElement",
+ "SvgTextContentElement",
+ "SvgGraphicsElement",
+ "Node",
+ "CssStyleDeclaration",
+ "DomRect",
+ "Event",
+ "EventTarget",
+ "MouseEvent",
+ "console",
+]
diff --git a/crates/modules/gioser/gioser-graph-web/src/lib.rs b/crates/modules/gioser/gioser-graph-web/src/lib.rs
new file mode 100644
index 0000000..db0f1d4
--- /dev/null
+++ b/crates/modules/gioser/gioser-graph-web/src/lib.rs
@@ -0,0 +1,496 @@
+//! `gioser-graph-web` — widget de grafo semántico SVG inline.
+//!
+//! Fetchea `GET /graph` de la API de gioser, parsea nodos + aristas,
+//! y renderiza un grafo SVG interactivo dentro de un contenedor dado.
+//! Los nodos son clicleables: al hacer clic en un nodo se navega a la
+//! página correspondiente (o se pasa un callback).
+//!
+//! ## Layout
+//!
+//! Usa un layout force-directed simple (Fruchterman-Reingold básico)
+//! implementado en Rust/WASM. No requiere canvas WebGL ni librerías
+//! externas. El SVG se renderiza inline y escala responsivamente.
+//!
+//! ## Contrato DOM
+//!
+//! El caller pasa un `
` contenedor y un callback `on_navigate(doc_id)`.
+//! El widget monta un `