toad.js
raw JSON → 0.3.4 verified Fri May 01 auth: no javascript
toad.js is a TypeScript GUI library for building desktop-style web applications using modern web technologies. Version 0.3.4 (March 2025) is in early development with weekly releases. It enforces a layered architecture (DDD/Clean Architecture) with Presentation Model pattern, focused on complex data-driven apps with large screens. Unlike React/Vue, it has no virtual DOM, no mobile support, and no eye candy — targeting pro users with consistent UIs. Requires Node >=21.7.1 and ESM only.
Common errors
error Error [ERR_REQUIRE_ESM]: require() of ES Module /node_modules/toad.js/index.js from ... not supported. ↓
cause Using require() instead of import.
fix
Change to dynamic import() or set type: module in package.json.
error TypeError: toad_js_1.TextModel is not a constructor ↓
cause Importing TextModel from root instead of 'toad.js/model'.
fix
Change import to: import { TextModel } from 'toad.js/model';
error Error: Cannot find module 'toad.js/model' ↓
cause Package not installed or import path misspelled.
fix
Ensure 'toad.js' is in package.json dependencies, and use correct case.
Warnings
breaking ESM-only package — require() will throw ERR_REQUIRE_ESM ↓
fix Use import syntax or dynamic import().
breaking Minimum Node.js version is 21.7.1 — older Node fails with engine check ↓
fix Update Node to >=21.7.1.
gotcha Models and Views are in subpaths, not root package exports ↓
fix Import from 'toad.js/model', 'toad.js/view', etc.
gotcha Package is pre-1.0 — API and import paths may change without semver major ↓
fix Pin to exact version and test upgrades.
Install
npm install toad.js yarn add toad.js pnpm add toad.js Imports
- Application wrong
const Application = require('toad.js');correctimport { Application } from 'toad.js' - TextModel wrong
import { TextModel } from 'toad.js'correctimport { TextModel } from 'toad.js/model' - View wrong
import { View } from 'toad.js'correctimport { View } from 'toad.js/view'
Quickstart
import { Application, Button, Dialog, Label, NumberModel, TextModel } from 'toad.js';
import { View } from 'toad.js/view';
class MyView extends View {
constructor() {
super();
this.count = new NumberModel(0);
this.label = new TextModel('Hello, TOAD!');
}
render() {
return `<div>
<label>${this.label.value}</label>
<button onclick="${this.onClick.bind(this)}">Count: ${this.count.value}</button>
</div>`;
}
onClick() {
this.count.value++;
this.label.value = `Clicked ${this.count.value} times`;
}
}
const app = new Application({
view: new MyView(),
title: 'TOAD Demo'
});
app.start();