A brutalist portfolio website built with Rust, WebAssembly, and Dioxus 0.7. Features an AI-powered chatbot that runs entirely in the browser using semantic search.
- Rust + WebAssembly — compiled to WASM via
wasm32-unknown-unknown - Dioxus 0.7 — reactive UI framework with client-side routing
- Transformers.js — runs
all-MiniLM-L6-v2(fp16) in-browser for semantic embeddings - Nix Flakes — reproducible dev environment and NixOS deployment module
- Home — hero section with interactive particle canvas
- Projects — project showcase with detail views
- Papers — research papers with detail views
- Chat — AI chatbot powered by semantic search over FAQ data
The chat page features a FAQ-based chatbot that uses:
- Semantic search — user queries are embedded with
all-MiniLM-L6-v2and matched against pre-computed FAQ embeddings via cosine similarity - TF-IDF fallback — keyword-based matching when embeddings are unavailable
- Conversational features — greeting detection, follow-up handling, response variation
- Privacy-first — the ML model runs locally in the browser, no data leaves the device
The ~44MB model is loaded on-demand when the user clicks "Load AI Model".
├── apps/
│ ├── porto-app/ # Main Dioxus WASM application
│ │ └── src/
│ │ ├── routes/ # One folder per route, colocated
│ │ │ # home/{_canvas,_components,_constants}
│ │ │ # projects/, papers/, chat/{_engine}
│ │ ├── components/ # Pure UI, no route or domain deps
│ │ ├── libs/ # Browser plumbing (event guard, sleep, rAF loop)
│ │ ├── data/ # Content loaders
│ │ └── styles/ # Theme and global stylesheet
│ └── shared/ # Shared data types
│ └── src/
├── content/ # TOML content files (about, projects, papers, FAQ)
├── public/ # Static assets (photos, papers, models, favicon)
├── nix/
│ └── module.nix # NixOS module (nginx, ACME, security headers)
├── Cargo.toml # Workspace root
├── Dioxus.toml # Dioxus build configuration
└── flake.nix # Nix devShell, packages, nixosModules.default
nix develop
dx serve --package porto-appnix develop -c dx bundle --package porto-appOutput: target/dx/porto-app/debug/web/public/
This flake exports nixosModules.default for use in a NixOS configuration:
# In your flake inputs:
web-porto.url = "github:KeyCode17/web-porto";
# In your machine config:
imports = [ web-porto.nixosModules.default ];
services.web-porto = {
enable = true;
domain = "daffakaryudi.web.id";
acmeEmail = "m.daffa.karyudi@gmail.com";
};