Workspace Class
A Workspace is the bridge between your JavaScript code and the EPANET (or EPANET-MSX) engine compiled to WebAssembly. It holds a virtual filesystem you can read and write — INP, RPT, OUT, hydraulics binary, MSX configuration — and it owns the loaded engine module that the Project class is built on top of.
Since epanet-js 0.9.0 the package ships two Workspace types:
- The standard
Workspace, imported fromepanet-js, bundles a v2.3.5 WASM binary as a Base64 blob. Does not require additional setup and runs straight from a CDN or a plain HTML page. - The slim
Workspace, imported fromepanet-js/slim, contains only the Emscripten loader. It requires loading any of the published EPANET engine versions, with or without MSX. Engine versions can be loaded by importing them fromepanet-js/engines/<version>. It allows switching engines at runtime and generates a smaller bundle.
Both expose the same file I/O methods. The difference is in how the engine is loaded.
Picking a loader
Section titled “Picking a loader”Use when you want to drop the library into a page or CDN-served script and want to run the latest EPANET version.
import { Workspace } from "epanet-js";
const ws = new Workspace();await ws.loadModule();The WASM binary is embedded as a Base64 string in the JS bundle. This makes generates slightly larger download sizes, but requires no extra configuration.
Use when you control the bundler (Vite, Webpack, Rspack, esbuild) and want smaller bundles, deterministic versioning, or MSX.
import { Workspace } from "epanet-js/slim";import { EpanetEngine } from "epanet-js/engines/v2.3.5-msx";
const ws = new Workspace();await ws.loadModuleVersion(() => Promise.resolve(EpanetEngine));Your bundler must emit the .wasm asset shipped next to the engine module. Most modern bundlers handle this automatically when they see the dynamic import; for Vite, no extra configuration is required.
Choosing an engine
Section titled “Choosing an engine”The slim loader can target any of these engine entry points. Append -msx to the import path for the MSX-enabled variant:
| Import path | EPANET version | MSX |
|---|---|---|
epanet-js/engines/v2.2 | 2.2 | — |
epanet-js/engines/v2.2-msx | 2.2 | ✓ |
epanet-js/engines/v2.3 | 2.3.0 | — |
epanet-js/engines/v2.3-msx | 2.3.0 | ✓ |
epanet-js/engines/v2.3.1 … v2.3.5 | 2.3.1 – 2.3.5 | — |
epanet-js/engines/v2.3.1-msx … v2.3.5-msx | 2.3.1 – 2.3.5 | ✓ |
epanet-js/engines/master | OWA master snapshot | — |
epanet-js/engines/master-msx | OWA master snapshot | ✓ |
epanet-js/engines/dev | OWA dev snapshot | — |
epanet-js/engines/dev-msx | OWA dev snapshot | ✓ |
Pick v2.3.5 for the recommended stable engine; pick v2.2 for parity with desktop EPANET 2.2; pick master / dev to track upstream EPANET as it evolves.
Once the engine is loaded, available API methods on Project are determined by what that engine exports — see the version badges on every project function for the exact compatibility matrix.
Switching engines at runtime
Section titled “Switching engines at runtime”The slim loader makes it easy to compare results between EPANET versions:
import { Workspace } from "epanet-js/slim";import { Project } from "epanet-js";
async function runOn(version: "v2.2" | "v2.3.5") { const ws = new Workspace(); await ws.loadModuleVersion(() => import(`epanet-js/engines/${version}`));
const project = new Project(ws); ws.writeFile("net.inp", inpText); project.open("net.inp", "report.rpt", "out.bin"); project.solveH(); // …read whatever values you need, then close project.close(); return ws.readFile("report.rpt");}See the Choosing an engine version example for a complete walkthrough.
Class methods
Section titled “Class methods”loadModule() standard only
Section titled “loadModule() ”Asynchronously loads the embedded EPANET v2.3.5 WASM module. Must be called before passing the workspace to new Project(...).
loadModule(): Promise<void>Only available on the standard Workspace from epanet-js. The slim workspace uses loadModuleVersion instead.
loadModuleVersion(engine) slim only
Section titled “loadModuleVersion(engine) ”Loads the engine module returned by the supplied callback. The callback is typically an import() of an epanet-js/engines/* entry, or a previously-imported module wrapped in Promise.resolve.
loadModuleVersion(engine: () => Promise<EpanetEngine>): Promise<void>| Parameter | Type | Description |
|---|---|---|
| engine | () => Promise<EpanetEngine> | callback that resolves to one of the engine variants. |
writeFile(path, data)
Section titled “writeFile(path, data)”Writes data to a file in the workspace’s virtual filesystem. Used to make INP and MSX files available to the engine.
writeFile(path: string, data: string | Uint8Array): void| Parameter | Type | Description |
|---|---|---|
| path | string | path inside the virtual filesystem (e.g. "net.inp"). |
| data | string | Uint8Array | file contents. Strings are written as UTF-8. |
readFile(file, encoding?)
Section titled “readFile(file, encoding?)”Reads back a file from the virtual filesystem. Useful for retrieving the generated report (.rpt) or the binary output (.bin) after a simulation.
readFile(file: string): string;readFile(file: string, encoding: "utf8"): string;readFile(file: string, encoding: "binary"): Uint8Array;| Parameter | Type | Description |
|---|---|---|
| file | string | path of the file to read. |
| encoding | ”utf8” | “binary” (optional) | "utf8" returns a string (default), "binary" returns a Uint8Array. |
getError(code)
Section titled “getError(code)”Translates a numeric EPANET error/warning code into the human-readable message stored in the engine.
getError(code: number): stringversion getter
Section titled “version ”The integer version of the loaded engine (e.g. 20305 for v2.3.5). Useful for runtime feature detection.
get version(): numberisLoaded getter
Section titled “isLoaded ”true once loadModule() / loadModuleVersion() has resolved.
get isLoaded(): boolean