WebOS/400 is an experimental, single-user browser environment inspired by IBM i (AS/400). It models libraries, objects, programs, jobs, subsystems, message queues, authority, auditing, source members, SQL and a 5250-style terminal.
This project intentionally has no backend. The kernel, terminal and applications run as ES modules in the browser; SQLite runs through sql.js/WebAssembly; the database is stored in IndexedDB. A service worker makes the application available offline after its first complete load.
The browser requires an HTTP origin for modules, WebAssembly, IndexedDB and service workers. The development server only serves static files and contains no application API.
npm run startOpen http://localhost:8080. The initial profile is QSECOFR and its initial password is QSECOFR; change it with CHGPWD.
npm test
npm run checkBoot follows this flow:
DatabaseManagerloads and validates the SQLite image from IndexedDB.- Authority, libraries, message queues, subsystems, jobs and programs are initialized.
QBATCHstarts anAUDITJRNPjob.QINTERstarts an interactiveSIGNONjob.- Programs return transitions to the dispatcher instead of recursively nesting menus.
Main components are under src/kernel/core/:
System: owns the local kernel lifecycle.DatabaseManager: SQLite/WASM, schema migrations, IndexedDB snapshots and integrity checks.ProgramManager: program catalog, qualified-name and*LIBLresolution, isolated invocation instances and call stacks.CommandProcessor: IBM i-style command parsing and execution.AuthorityManager: profiles, PBKDF2 password hashes, groups and object authorities.JobManager/SubsystemManager: job admission, membership, lifecycle and accounting.MessageQueue: FIFO delivery, timed receivers and broadcast listeners.Terminal: 24x80 presentation, forms, PF keys, cursor editing and accessibility output.
The browser is the trust boundary. Authority checks accurately model system behavior inside the experiment, but they are not protection against a user who controls DevTools or modifies local IndexedDB data.
The primary SQLite image is webos400.db in IndexedDB. Every persisted change retains the previous valid image as webos400.backup.db. Startup executes PRAGMA integrity_check; if the primary is damaged, the recovery image is installed automatically.
SAVSYSdownloads a validated SQLite snapshot.RSTSYSvalidates and installs a selected snapshot, retaining the current image as recovery data before reload.- Schema version 5 includes composite program keys, user/group authorities, audit indexes, source-member metadata, batch queues and spool files.
The service worker caches local modules and the sql.js runtime after use. Data never leaves the browser unless the user explicitly downloads a SAVSYS file.
The main-menu field accepts a menu option, a program name or an IBM i-style command. Names are case-insensitive; parameter values can be quoted.
CRTLIB LIB(DEVLIB) TEXT('Development library')
CRTSRCPF FILE(DEVLIB/QRPGLESRC) RCDLEN(112) TEXT('RPG sources')
ADDPFM FILE(DEVLIB/QRPGLESRC) MBR(HELLOWORLD)
STRPDM FILE(DEVLIB/QRPGLESRC)
DSPFD FILE(DEVLIB/QRPGLESRC)
CHGCURLIB CURLIB(DEVLIB)
ADDLIBLE LIB(DEVLIB) POSITION(*FIRST)
RMVLIBLE LIB(DEVLIB)
STRSBS SBS(QBATCH)
ENDSBS SBS(QCMN)
ENDJOB JOB(000002/QSECOFR/AUDITJRNP)
GRTOBJAUT OBJ(DEVLIB/HELLO) OBJTYPE(*PGM) USER(DEVELOPER) AUT(*USE)
CALL PGM(QSYS/MAIN)
SBMJOB CMD('CRTLIB LIB(BATCHLIB)') JOB(CRTBATCH)
Object commands supported directly include CRTLIB, DLTLIB, CRTFILE, CRTSRCPF, DLTFILE, ADDMBR/ADDPFM, RMVMPR/RMVM, and CLRMBR/CLRPFM.
Interactive system programs currently include:
- Development:
STRPDM,EDTSRC,STRSQL,RUNQRY,CRTSRCPF,ADDMBR,ADDREC,CLRMBR. - Objects and libraries:
WRKOBJ,WRKLIB,DSPLIBL,DSPFD,CRTLIB,DLTLIB,CRTFILE,DLTFILE. - Operations:
WRKJOB,DSPJOB,WRKSBS,SBMJOB,WRKJOBQ,WRKSPLF,DSPSPLF,DSPMSG,SYSSTATUS. - Users and auditing:
WRKUSRPRF,CRTUSRPRF,DSPUSRPRF,CHGPWD,DSPAUDLOG,DSPAUDMON,AUDITJRNP. - Browser system:
WRKTERM,SAVSYS,RSTSYS,SIGNON,MAIN.
STRPDM supports creating, editing, copying, deleting, displaying and renaming members. EDTSRC saves source pages transactionally. STRSQL allows reads for signed-on profiles and restricts mutation to QSECOFR/*ALLOBJ.
Create a class extending Program, then register it in ProgramManager.registerSystemPrograms():
import { Program } from '../../kernel/core/Program.js';
export default class HELLO extends Program {
constructor(system) {
super('HELLO', 'QSYS', system);
this.description = 'Example program';
}
async execute() {
this.clearTerminal();
this.writeToTerminal(2, 2, 'Hello from WebOS/400');
this.terminal.beginForm([], null);
this.terminal.renderScreen();
await this.waitForInput();
}
}Every invocation receives a new object instance. ProgramManager records it in the job call stack and resolves unqualified names through the job's current library and *LIBL.
WebOS/400 emulates operating-system concepts rather than running IBM i binaries. Jobs are cooperative JavaScript tasks, SQL tables represent object storage, the terminal is a browser component, and all users share one local browser image. Those constraints are deliberate: this is a browser-native laboratory, not an IBM i compatibility layer or a secure multi-user server.