The Problem
rzweb solves the accessibility problem of Rizin, the powerful reverse engineering framework, by bringing it to the browser via WebAssembly. Engineers can analyze binaries locally without installing Rizin or uploading files to remote servers, but the client-side architecture introduces maintainability concerns around code quality and deployment pipelines.
What This Does
rzweb is a browser-based reverse engineering platform built on Rizin that runs entirely client-side via WebAssembly. The React + Tailwind frontend (53 source files in src/) provides views for terminal access, disassembly, control flow graphs, hex dumps, and string extraction. State management uses Zustand, the terminal is powered by xterm.js, and Rizin binaries are loaded from the companion rzwasi repository. Files are processed locally—binaries never leave the user's device—with supported formats including ELF, PE/PE+, Mach-O, and Raw. The project structure organizes code into src/components (UI and views), src/lib/rizin (Rizin integration), src/lib/utils (helpers), src/stores (state), src/pages, and src/providers. Entry points include index.html, src/main.tsx, and component index files that wire the UI together.
How It Is Wired
Execution starts at src/providers/ThemeProvider.tsx:46 with the handler function, which reaches one function and is called by nothing else in the repo. The internal call graph contains 76 resolved call edges between repository functions, with cn called from 33 places and executeCommand from 8 places. The most connected modules are src/components/ui/index (Ce 13), src/components/views/index (Ce 5), and src/stores/index (Ce 5). Effects outside the repo are limited to 3 functions that read or write files: src/lib/rizin/RizinInstance.ts, src/pages/AnalysisPage.tsx, and src/components/file/FileDropZone.tsx. File routing flows through stores (src/stores/fileStore.ts, src/stores/rizinStore.ts, src/stores/uiStore.ts) and providers (src/providers/ThemeProvider.tsx), with src/lib/rizin/RizinInstance.ts and src/lib/rizin/RizinLoader.ts handling the Rizin WASM module lifecycle. The module dependency graph has 58 internal modules with 38 import edges and no circular dependencies, but the high branching density in src/lib/utils/version.ts (15 branch points over 45 lines) and deep nesting in three view files (max indentation depth 8) indicates control flow that is hard to follow.
How To Use It
Setup: Clone the repository verbatim:
git clone https://github.com/moses-y/rzweb
cd rzweb
npm install
Configuration: No environment variables or keys are required. The project uses Vite (vite.config.ts), Tailwind (tailwind.config.ts), and ESLint (tsconfig.json, .eslintrc.json) as defined in the root config files.
Running it: Start the development server:
npm run dev
Then open the browser to the local URL. Drop a binary file onto the page or select one via the file zone. Click Analyze to load the binary into the WebAssembly Rizin instance. The terminal accepts Rizin commands (e.g., pdf, afl, px), and views update accordingly. For production builds, npm run build generates static assets.
Real-World Use
A security analyst needs to quickly inspect a suspicious binary received via email. Instead of installing Rizin locally or running it in a sandbox, they open rzweb in a browser, drop the binary onto the page, and immediately have access to a fully functional terminal and analysis views. The analyst runs aa to perform full analysis, afl to list functions, and pdf to disassemble functions of interest. Strings extracted via the Strings view reveal hardcoded API keys and embedded URLs. Because all processing occurs client-side, no binary data leaves the analyst's machine, satisfying air-gapped environment constraints. The control flow graph view helps identify obfuscated jump targets, and the hex dump view allows byte-level inspection of suspicious sections.
Code Health & Issues
- HIGH - Add a test suite; this repository has none (58 source files, no test files). Any change ships with no signal that existing behaviour still holds, so a regression reaches production undetected.
- HIGH - Add a workflow that builds and tests this repository (57 source files, no CI configuration). Every change merges with nobody having run the build once.
- MEDIUM - Enable Dependabot or Renovate (1 manifest, no update bot configured). Without a bot a published advisory sits unpatched until someone audits by hand.
- MEDIUM - Review the install lifecycle script and disable scripts in CI -
package.jsoncontainspostinstallwhich is the execution vector for every npm compromise. - LOW - Add the repository convention files this project lacks (missing
.editorconfig,.gitattributes, a formatter config).
The Bottom Line
This is a functional, privacy-respecting browser-based Rizin frontend that lowers the barrier to entry for binary analysis. The client-side-only architecture is its strongest feature, but the absence of tests, CI, and dependency automation represents a genuine risk for any production use. Engineers who need a quick, local analysis surface will find it immediately useful; teams requiring reliable long-term maintenance should prioritize the test and CI gaps before depending on it for critical work.