A browser-based modelling workbench for the EPA Storm Water Management Model. Open a .inp file, edit the model, run it on any of five engines — including EPA SWMM 5.2.4 and OpenSWMM 6 compiled to WebAssembly, running entirely in the browser — then interrogate the results with tools that go well past the standard report: phase-space diagnostics, a calculation-level engine inspector, LID unit animation, 3D network playback, and side-by-side engine comparison.
No desktop install, no upload step for the in-browser engines: the model never leaves the tab unless you ask it to.
Three cooperating layers:
- Client (
client/) — TypeScript + Vite + Tailwind single-page app. Handles.inpload and edit (subcatchments, nodes, links, LID controls, options), map and table views, and results visualisation. The WASM engines run here, in a web worker, so a model can be simulated without leaving the tab. - Server (
server/) — Node + Express orchestration. Invokes the native engine, proxies the cloud batch runner, browses GitHub repositories, and exposes an MCP endpoint for programmatic or AI-assisted interaction. Stateless: results are held per instance, not in a database. - Engines (
swmm-engine/,client/public/) — the SWMM computational cores in C and C++, compiled native and to WebAssembly. Never reimplemented in JavaScript, so numerical fidelity with the reference engines is preserved.
Modelling coverage follows the underlying engines: rainfall/runoff, hydraulic routing, snow accumulation and melt, pollutant buildup and washoff, and LID controls — with the SWMM 6 LID caveat below.
The engine is switchable at runtime from the toolbar chip (bottom status bar shows which one is live). Each produces the same .rpt / .out artifacts, so every downstream view works regardless of which engine ran.
| Mode | Engine | Runs where |
|---|---|---|
| WASM 5.2.4 | EPA SWMM 5.2.4 compiled to WebAssembly | In the browser, in a web worker |
| WASM 6 rel | OpenSWMM 6 (swmm6_rel) compiled to WebAssembly |
In the browser, in a web worker |
| WASM 6 dev | OpenSWMM 6 (develop branch) compiled to WebAssembly | In the browser, in a web worker |
| Local 5.2.4 | Native swmm-engine/runswmm binary |
On the machine serving the app |
| Remote 5.2.4 | Cloud batch runner service | Off-box, for long or bulk runs |
| Mock | Synthetic results generator | In the browser (UI development only — results are clearly badged as synthetic) |
Three comparison modes run two engines on the same model in one pass and diff the outcome: SWMM 5 vs SWMM 6 release, SWMM 5 vs SWMM 6 develop, and SWMM 6 release vs develop. Differences surface as scatter plots (node depth, link flow, continuity) plus a verdict — match, differs, or inconclusive.
SWMM 6 LID caveat. The OpenSWMM 6 port's LID module is incomplete: several control parameters are unconverted and its flux equations are unit-inconsistent. Do not trust LID results from the SWMM 6 engines. Use WASM 5.2.4 or the native engine for any LID work. See
.agents/memory/swmm6-lid-port-gaps.md.
Model editing
- Full
.inpparse and write, with a round-trip audit that reports anything the writer changes - Property editor, section grid views, group edit, transect and curve/time-series editors
- Network map with theming, profile plots, find-object, split-screen compare
- Import from CSV (nodes/links), DXF and GeoJSON; export to CSV and DXF
- Autosave, undo/redo, and provenance badges tracking where each result came from
- 20 bundled sample models (EPA Extran 1–10, Greenville US/SI, User 1–5)
- Open models straight from a GitHub repository by browsing its folders
Results and visualisation
- Time-series and table views, frequency analysis, statistics reports, calibration overlays
- Phase-space diagnostics — flow–depth trajectories, derivative fields and instability indexes that expose oscillation, chatter and reversals that ordinary time-series plots hide, plus an attention sweep that ranks the worst-behaved links
- 3D viewer — the network rendered in three dimensions with animated results playback and GIF export
- LID viewer — reads the consolidated
.liddetailed-output report (one file covering every LID unit) and animates each unit's water balance layer by layer: surface, pavement, soil, storage, drain - Diagram gallery and schematic image export
Diagnostics
- Engine Health dashboard — continuity errors, timestep explorer, and the assumptions the engine actually applied, parsed from the
.rpt - Engine Inspector — a calculation microscope that reproduces the engine's own arithmetic for a chosen element so you can see how a number was reached
- Model Health — pre-run checks for the classic SWMM modelling mistakes
- CFL analysis — Courant-based stable-timestep estimates per conduit, with discretisation suggestions
- Round-trip audit — reparses everything the app writes and reports any field it altered, omitted or invented
- Diff tool — compare two
.inpfiles section by section - Batch runner — queue many models across engines, with cancel, run in a worker so the UI stays responsive
- AI Assist panel — rule-based model review that runs locally; no external service, no data leaves the browser
The server exposes a Model Context Protocol endpoint at POST /mcp, so an AI agent can run SWMM directly:
| Tool | Purpose |
|---|---|
run_swmm_simulation |
Run a full .inp on the native engine; returns status, error/warning lines and continuity errors, optionally the whole .rpt |
get_report_section |
Run a model and return only named report sections (e.g. "Node Depth Summary", "Flow Routing Continuity") |
engine_status |
Report whether the native engine is available on this server |
Set the MCP_API_KEY secret to require it as a bearer token. If it is unset the endpoint accepts unauthenticated calls, so set it before exposing a deployment publicly.
| Route | Purpose |
|---|---|
GET /api/swmm/status |
Native engine availability and the path it was probed at |
POST /api/swmm/run |
Run a model on the native engine |
POST /api/swmm/run-or-proxy |
Run natively, or forward to the cloud runner if the native engine is absent |
GET /api/swmm/out/:id |
Fetch a parked large .out result as gzip |
/api/swmm-proxy/* |
Cloud batch runner: upload, start, status, results |
GET /api/github-browse, GET /api/fetch-github |
Browse and load .inp files from a GitHub repository |
| Folder | Purpose |
|---|---|
client/ |
React + Vite front end (client/src/pages/swmm-ui.tsx is the workbench shell) |
client/public/ |
WASM engines (swmm_engine.wasm, wasm6/, wasm6dev/), the 3D viewer, sample models, help content |
server/ |
Express server: engine orchestration, cloud proxy, GitHub browsing, MCP |
swmm-engine/ |
Native SWMM sources and the runswmm binary, plus engine patches |
shared/ |
Types shared by client and server |
script/, scripts/ |
Build script; parity and post-merge helpers |
tests/ |
Automated suites — see below |
docs/ |
Reference notes (e.g. engine graph variables) |
.agents/memory/ |
Engineering notes on engine quirks, file formats and build recipes |
git clone https://github.com/dickinsonre/Swmm5-UI-Engine.git
cd Swmm5-UI-Engine
npm install
npm run dev # serves the app on http://localhost:5000The in-browser WASM engines work immediately. The Local engine additionally needs swmm-engine/runswmm built for your platform; if it is missing, the app falls back to WASM and the engine tooltip tells you where it looked.
| Script | Does |
|---|---|
npm run dev |
Development server (client + API on port 5000) |
npm run check |
TypeScript typecheck |
npm test |
Six headless suites: round-trip audit, calibration, CFL, engine scatter, batch verdict, binary .out offsets |
npm run test:e2e |
Browser end-to-end suites — requires the app already running |
npm run build |
Typecheck, run tests, then bundle. A failing check or suite blocks the build |
- Frontend: React 18, TypeScript, Vite, Tailwind CSS, Radix UI, wouter, TanStack Query, Recharts
- Backend: Node 20 + Express (TypeScript, run through
tsx). Stateless — no database - Engines: EPA SWMM 5.2.4 (C) and OpenSWMM 6 (C++), native and compiled to WebAssembly via Emscripten
- 3D: three.js
- Binary
.outresults are loaded up to 5,000 reporting steps. Longer runs are sampled uniformly (every Nth period, always including the final one) so the series still spans the whole simulation, and the UI labels the results as sampled — but peaks falling between sampled periods are not plotted. Read exact peaks from the.rptreport. - Pollutant columns are read from the
.outheader but water-quality series are not yet surfaced in the UI - LID results from the SWMM 6 engines are not trustworthy (see above)
- Large results are held per server instance, so a horizontally scaled deployment can lose track of one
A single-maintainer project, developed iteratively with Replit Agent. Issues and pull requests are welcome. Before starting, read HANDOVER.md for in-progress work and .agents/memory/ for the engineering notes that explain why several non-obvious things are the way they are — binary .out layout, engine build recipes, parser traps. Planned work is tracked in the project task list rather than in this file, so it does not go stale here.
Anything that changes an engine, an engine build, or a parser needs a verification pass, not just a green typecheck: npm test must stay green, and engine-facing changes should be checked against the discipline in .agents/skills/corinne-testing/.
EPA SWMM is developed by the US Environmental Protection Agency; OpenSWMM 6 by the HydroCouple/OpenSWMM project — Caleb Buahin (lead developer), Corinne Wiesner-Friedman (developer, documentation, technical review) and Scott Jeffers (documentation and outreach). This project is part of Robert Dickinson's broader SWMM tooling ecosystem, which spans SWMM3 through SWMM6, XPSWMM, ICM SWMM and InfoDrainage.
SWMM5-UI's own code is released under the MIT License. That covers this interface only — the bundled simulation engines are separate works under their own terms, and those terms travel with any copy of this project.
This project bundles two builds of the OpenSWMM 6 engine, from two upstream branches under two different licenses, plus the public-domain EPA engine:
| Bundled engine | Upstream | License |
|---|---|---|
OpenSWMM 6, release (client/public/wasm6) |
HydroCouple/openswmm.engine branch swmm6_rel, 6.0.0-alpha.3 |
Apache-2.0 © 2026 HydroCouple Developers — text, NOTICE |
OpenSWMM 6, develop (client/public/wasm6dev) |
same repo, branch develop |
MIT © 2026 Caleb Buahin — text |
| EPA SWMM 5.2.4 | USEPA | Public domain, 17 USC § 105 |
Branch trap: that repository is not one license.
mainis MIT (© 2025 HydroCouple);developis MIT (© 2026 Caleb Buahin, no NOTICE file);swmm6_rel, the 6.0.0 release line, is Apache-2.0 with a NOTICE file. GitHub's sidebar shows "Other License" because of the split. Never quote themainREADME's MIT line for a 6.0.0 build, and never copy the release build's Apache notice onto the develop build.
Both engine builds were modified before compilation to WebAssembly — Emscripten platform and threading fixes, plus a consolidated LID report in the release build. The patch inserts an Apache-2.0 §4(b) change notice at the top of every file it touches; per-file detail in swmm-engine/patches/MODIFICATIONS.md.
The bundled EPA SWMM 5.2.4 solver is also modified — three files, for the consolidated .lid report. EPA SWMM is public domain, so no notice is required, but the change is documented and reproducible anyway: docs/swmm5-modifications.md has the census, the five ways to show the diff, and the parity evidence; the patch is swmm-engine/patches/swmm5-lid-consolidated-report.patch.
The exact upstream commit behind each artifact was not recorded at build time — only the branch. Both are moving alpha lines, so record the SHA on the next rebuild.
Portions derive from the USEPA Storm Water Management Model, which is in the public domain under 17 USC § 105. Neither the USEPA nor HydroCouple endorses this product; "EPA", "USEPA", "SWMM", "OpenSWMM" and "HydroCouple" are used solely to describe the origin of the software included here. This is not an official EPA, HydroCouple or OpenSWMM release.
Deploying this app, embedding its engine in a single-file HTML build, or pushing it to a repo or gist is redistribution, and the Apache-2.0 §4 conditions apply to all three. Before publishing, work through docs/swmm6-attribution.md; tests/attribution.test.ts enforces the mechanical half of that checklist on every build.