JavaScript POC for a fully user-modifiable software system
Clone or download
Latest commit 722b349 Aug 25, 2018


JavaScript POC for a fully user-modifiable software system.

The goal is to create a software system that escapes the rigid boundaries of conventional software tools and programming languages by empowering the end-user to create their own experience through direct-manipulation. Everything within the system (including all parts of the system itself) will be composed of "objects" that can be created & modified through a visual interface, and thus everything about the system can be modified while you are using it. (Discuss on forum, or see Motivation further down)

How is this possible?

The "things" in a computer exist only as representations -- in other words, it's all just structured information. Traditionally, everything is stored as raw data without any explicit structure, and each software tool must convert it into a structure that can be viewed or manipulated in some meaningful way. If instead, everything was stored in an explicit structural form to begin with, then you could directly modify everything however you want, rather than only doing what each software tool allows. This structure will consist of "objects" that can be modifed in place and combined to form any ad-hoc structure of information. And since "code" is nothing more than structured information for "what to do" (code is data), this means creating & modifying whatever "things" and behaviors you want.

What will it look like?

All that matters here is that there is any interface to begin with, because the end-user can then manipulate it into whatever they want. This calls for a minimal interface just good enough to allow one to see and manipulate the structure of everything. And by making it a visual interface (GUI), the user's ability to modify it also means that they can create whatever graphical representation or tool that is most ideal for each scenario. For example, editing the size & position of a ball by clicking and dragging a ball, rather than by editing numeric data about a ball (see Brett Victor's "Dynamic Visualizations" and "Learnable Programming").

Implications for Programming


Every operation that can be performed on an object (and thus on any part of the system), is itself stored as an object within the system. Thus, everything that happens within the system -- whether it be from user-interaction or from running code -- is accomplished by triggering one or more of these operations. This dissolves the boundary between "programming" (API) and user-interaction (UI), because the end-user can now do anything that code can do, and vice versa.



(Alan Kay's "Computer revolution hasn't happened yet"; Kay, Engelbart, Alexander all tried to expand human aspects; Brett Victor; programming is generally awful, and a better interface is needed to see enough to do it right. Also, every other software tool other than programming has a better interface than text. Something non-perscriptive, but open-ended and exploratory)


  1. Make an interpreter that executes code provided in the form of an AST object-graph. The operations (grammar) allowed in the AST consist mainly of the operations for manipulating AST objects (get, set, exists, delete, etc.) is built upon a similar small set of verbs). These operations are defined as objects within a built-in AST, and can thus all be modified at runtime. This AST is expanded at runtime through layers of "activation frames" (call stacks), allowing for context-dependent operations (DSLs). The interpreter can also execute "native" (JavaScript) functions stored within AST code (this is necessary to establish a set of base operations), and thus the system can be extended with new "native" functionality at runtime. The interpreter is also inserted into the built-in AST so that it can itself be accessed and modified at runtime (see step 3). This interpreter is the only part of the system coded directly in JavaScript. Everthing else following is code in terms of objects within the AST.

  2. Create an interactive UI (visual interface) as the sole means for interacting (as an end-user) with the system. For now, this just provides a generic way to inspect and edit AST objects in a visual interactive fashion. (This requires some "native" code for graphics and user interaction, but all of it is coded into the AST). This voids the need for a REPL, since AST objects to be created, modified, and executed directly in a visual manner.

  3. Create a serializer that serializes the entire runtime system into JavaScript source code. This is accomplished by serializing the whole system as a single JSON object, wrapped by JavaScript code which creates this object and initializes the UI (by invoking the interpreter on the UI "startup" code). From this point, further modification of the system can be done entirely through the interactive UI.

  4. Create a Compiler that convert AST objects (at least the ones needed for step 5) into native JavaScript code. (It might be possible to make this work for all ASTs by altering the interpreter to collect (rather than execute) all the "native" code that it encounters ... I'll have to look into that more).

  5. "Bootstrap" the interpreter by re-coding it as an AST object-graph (like everything else). The intpreter can now be edited entirely in AST form, and then compiled to replace the existing "native" interpreter. (The AST interpreter could also just run on top of the "native" one to test it amid modifications). Now the Entire system is modifiable in AST form.

  6. By creating compilers for other platforms, the entire system can transfer itself to any other environment or machine. And since everything is written in the high-level language of the system, everything from the old system "comes with". In this way, the system becomes capable of transferring itself from platform to platform (and back again) ... Kind of like Ultron :)


  1. Open a blank tab in your web-browser (enter "about:blank" into the address bar).
  2. Open the developer console (press F12).
  3. Copy the contents of Objects.js and paste it into the developer console, and then hit "enter" or click the "run" button.
  4. Observe the results in the console and on the blank page.
  5. You can try entering single commands by typing "Test(null, [...])" (where "..." is the code to run) into the console. (After step 3, you should already see some examples that have run in the console).