A Simulink-like block-diagram simulation framework for modeling and solving dynamic systems. Build circuit models (RLC, etc.) visually, connect blocks, and run ODE-based simulations with real-time results streamed via WebSocket.
| Tool / Dependency | Tested Version | Notes |
|---|---|---|
| Python | 3.13.9 | Must use python3.13 — see warning below |
| Node.js | 16.15.0 | |
| npm | 8.18.0 |
Python 3.14.1 warning: NetworkX 3.6 is incompatible with CPython 3.14.1 due to a known
dataclasses.__annotate__bug (AttributeError: 'wrapper_descriptor' object has no attribute '__annotations__'). Always create the venv withpython3.13, notpython3(which may resolve to 3.14 on your system).
| Package | Version |
|---|---|
| FastAPI | 0.135.1 |
| Uvicorn | 0.42.0 |
| Pydantic | 2.12.5 |
| NumPy | 2.4.3 |
| SciPy | 1.17.1 |
| NetworkX | 3.6.1 |
| pytest | 9.0.2 |
| httpx | 0.28.1 |
| pytest-asyncio | 1.3.0 |
| Package | Version |
|---|---|
| React | ^18.3.1 |
| @xyflow/react | ^12.10.1 |
| Recharts | ^3.8.0 |
| Zustand | ^5.0.12 |
| Vite | ^4.5.3 |
| TypeScript | ^5.5.3 |
cd backend
# Install dependencies with uv (recommended — uses workspace config)
uv sync --devAlternative (pip): If you prefer pip, create a venv with
python3.13 -m venv .venv, activate it, and runpip install -e ".[dev]".
cd frontend
npm installStart the entire system (backend + frontend) with a single command:
./start.shThe script will:
- Check for required dependencies (
uv,node,npm) - Install/sync backend and frontend dependencies
- Start the backend API server (uvicorn on port 8000)
- Start the frontend dev server (Vite on port 5173)
- Clean up all processes on
Ctrl+C
| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend API | http://localhost:8000 |
| API Docs | http://localhost:8000/docs |
| Health Check | http://localhost:8000/health |
If you prefer to start services individually:
cd backend
uv run uvicorn blocksim.api.app:create_app --factory --reloadThe API will be available at http://localhost:8000. Key endpoints:
GET /health— Health checkGET /api/...— REST API routesWS /ws/...— WebSocket endpoints for real-time simulation streamingGET /docs— Interactive Swagger API documentation
cd frontend
npm run devThe frontend will be available at http://localhost:5173 (Vite default).
cd backend
uv run python -m pytest tests/ -vcd frontend
npm run lint # ESLint checks
npm run build # TypeScript compilation + Vite buildblocksim/
├── start.sh # Quick-start script (backend + frontend)
├── backend/ # Python simulation engine + REST/WebSocket API
│ ├── pyproject.toml # Python project config & dependencies
│ ├── blocksim/
│ │ ├── core/ # Engine core
│ │ │ ├── block.py # Block ABC — base class for all blocks
│ │ │ ├── solver.py # ODE solvers (Euler, RK4, SciPy RK45, Radau)
│ │ │ ├── graph.py # Dependency graph & topological sorting
│ │ │ └── system.py # System assembly, connection wiring, simulation loop
│ │ ├── blocks/ # Built-in block library
│ │ │ ├── sources.py # Signal sources (Step, Sine, Constant, Ramp)
│ │ │ ├── sinks.py # Signal sinks (Scope, Logger)
│ │ │ ├── electrical.py # RLC components (Resistor, Inductor, Capacitor)
│ │ │ ├── math_ops.py # Math operations (Gain, Sum, Integrator)
│ │ │ ├── delays.py # Delay blocks (UnitDelay, TransportDelay)
│ │ │ ├── registry.py # Block type registry (auto-discovery)
│ │ │ └── EXTENDING.md # Guide for adding custom blocks
│ │ ├── models/ # Pydantic schemas
│ │ │ ├── schemas.py # API request/response models
│ │ │ ├── persistence.py # Model file save/load with versioning & export
│ │ │ └── validator.py # 3-level model validation (schema/referential/semantic)
│ │ └── api/ # FastAPI application
│ │ ├── app.py # Application factory (create_app)
│ │ ├── routes.py # REST API endpoints (CRUD, export, import, validate)
│ │ ├── ws.py # WebSocket endpoints
│ │ ├── store.py # In-memory model store
│ │ └── dependencies.py # FastAPI dependency injection
│ └── tests/ # pytest test suite
│ ├── test_block.py # Block ABC tests
│ ├── test_solver.py # Solver accuracy tests
│ ├── test_graph.py # Graph & topological sort tests
│ ├── test_system.py # System integration tests
│ ├── test_api.py # API endpoint tests (httpx)
│ ├── test_schemas.py # Pydantic schema validation
│ ├── test_persistence.py # Model save/load tests
│ ├── test_error_ux.py # Error handling UX tests
│ ├── test_performance.py # Performance benchmarks
│ └── test_blocks/ # Per-block-type tests
├── frontend/ # React UI — block-diagram editor
│ ├── package.json
│ ├── vite.config.ts
│ └── src/
│ ├── App.tsx # Root component
│ ├── api/ # API client (fetch/WebSocket)
│ ├── components/
│ │ ├── BlockCanvas.tsx # React Flow diagram canvas
│ │ ├── BlockNode.tsx # Custom block node renderer
│ │ ├── BlockPalette.tsx # Drag-and-drop block palette
│ │ ├── PropertyPanel.tsx # Block parameter editor
│ │ ├── SimulationChart.tsx # Recharts real-time plot
│ │ └── SimulationControls.tsx # Run/stop/configure controls
│ ├── store/
│ │ └── useModelStore.ts # Zustand state management
│ └── types/ # TypeScript type definitions
└── examples/ # Example simulation configurations
├── rlc_series.json # RLC series circuit (JSON model)
└── rlc_series.py # RLC series circuit (Python script)
Models can be exported as .blocksim.json files and re-imported later (or shared with other users). The export envelope includes:
- Schema version — for forward compatibility
- SHA-256 checksum — detects file tampering or corruption
- Timestamp & BlockSim version — provenance metadata
| Endpoint | Method | Description |
|---|---|---|
/api/models/{id}/export |
GET |
Download a model as a .blocksim.json file |
/api/models/import |
POST |
Upload and import a .blocksim.json file (multipart) |
/api/models/{id}/validate |
POST |
Run 3-level validation on a stored model |
- Files up to 10 MB are accepted.
- On import, the model goes through 3-level validation:
- Schema — Pydantic structural validation
- Referential — connection and block reference integrity
- Semantic — domain-specific rules (e.g., valid parameter ranges)
- If a checksum is present, it is verified and any mismatch is reported as a warning.
- Models are stored even if validation finds non-blocking issues, so users can fix problems interactively.
The simulation engine includes robustness features:
- Divergence detection — if a solver step produces
NaNorInf, the engine raises aSimulationDivergenceErrorwith the exact time step, block, and context. - Structured error responses — all domain exceptions (algebraic loops, duplicate blocks, invalid connections, schema version mismatches, etc.) are caught and returned as JSON with appropriate HTTP status codes.
- Adaptive solvers — for stiff systems (like RLC circuits), use the
radausolver which automatically adjusts step size.
| Solver | Type | Best For |
|---|---|---|
euler |
Fixed-step | Testing, simple systems |
rk4 |
Fixed-step | General-purpose (default) |
scipy_rk45 |
Adaptive | Smooth non-stiff ODEs |
radau |
Implicit adaptive | Stiff systems (RLC circuits) |
This project is licensed under the MIT License. See the LICENSE file for details.
Contributions are welcome! To get started:
- Fork this repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m "Add my feature" - Push to the branch:
git push origin feature/my-feature - Open a Pull Request against
main
Please make sure all tests pass before submitting your PR:
# Backend
cd backend && uv run python -m pytest tests/ -v
# Frontend
cd frontend && npm run lint && npm run build