SqueakJS is a runtime engine for Squeak Smalltalk written in pure JavaScript. It also works for many other OpenSmalltalk-compatible images.
Embedding a Smalltalk application in your webpage can be as simple as:
SqueakJS.runSqueak(imageUrl);
but you probably want to give it some more options (refer to the examples).
The interpreter core is divided in a number of vm.*.js modules, internal plugins in vm.plugins.*.js modules and external plugins in the "plugins" directory. The Just-in-Time compiler is optional ("jit.js") and can be replaced with your own.
There are a number of interfaces:
- browser: the regular HTML interface lets you use SqueakJS on your own web page. Just include "squeak.js".
- headless browser: a headless VM. It lets you use SqueakJS in your browser without a direct UI (you can create your own UI with a plugin). Include "squeak_headless.js" and add an "imageName" parameter to your website URL (eg. https://example.com/my/page.html?imageName=./example.image) or call the Javascript function "fetchImageAndRun('https://example.com/my/example.image')" to start the specified image.
- Node.js: another headless VM. It lets you use SqueakJS as a Node.js application via "node squeak_node.js ".
For discussions, please use the vm-dev mailing list. Also, please visit the project home page!
Simplest
- Run a minimal image. This is the simple demo included in this repo.
- Or run Etoys. Everything except the image and template files is in this repo.
- Or similarly, Scratch, also in here.
Run your own Squeak image in the browser
- Drag an image from your local files into the launcher.
- ... and all the other demo pages (see above) accept dropped images, too.
Run your own Squeak image from the command line
- Install a recent version of Node.js
- Run example image:
node squeak_node.js headless/headless.image
Run an interactive shell based on WebSocket communication with Cuis image
- Install a recent version of Node.js
- Go to ws and execute
start_server.shin a first shell andstart_client.shin a second shell. - After initialization it should be possible to issue Smalltalk statements which will be executed in the Smalltalk image.
- Try commands like:
Object allSubclasses size1837468731248764723 * 321653125376153761Collection allSubclasses collect: [ :c | c name ]
Which Browser
All modern desktop browsers should work. Mobile browsers work too, but most Squeak images assume a keyboard and mouse. YMMV.
Fixes to improve browser compatibility are highly welcome!
If your browser does not support ES6 modules try the full or headless SqueakJS VM as a single file (aka bundle) in the Distribution directory.
-
clone the github repo:
git clone https://github.com/codefrau/SqueakJS.gitor download and unpack the ZIP archive
-
serve the SqueakJS directory using a local web server.
TIP: If you have Node.js, try
cd SqueakJS npx servewhich will run a webserver on port 3000.
-
in a web browser, open http://localhost:3000/run/ and pick one of the images, or drag and drop your own
Now Squeak should be running. The reason for having to run from a web server is because the image is loaded with an XMLHttpRequest which does not work with a file URL. Alternatively, you could just open SqueakJS/run/index.html and drop in a local image.
- select your preferred type of interface (browser or headless)
- use the appropriate file (
squeak_bundle.jsresp.squeak_headless_bundle.js) from the Distribution directory - you can also build minified bundles using
npm run build
- use any text editor
- you have to reload the page for your changes to take effect
- easiest for me is if you create a pull request
- otherwise, send me patches
Contributions are very welcome!
SqueakJS is intended to run any Squeak image. It can already load any image from the original 1996 Squeak release to the latest Cog-Spur release, including 64-bit and Sista variants. But various pieces (primitives in various plugins) are still missing, in particular 3D graphics and networking (however, see Croquet which supports both, but should be generalized). Also, we should make pre-Spur 64 bit images load. And, it would be nice to make it work on as many browsers as possible, especially on mobile touch devices.
As for optimizing the way to go is an optimizing JIT compiler. The current JIT is very simple and does not optimize at all, it only eloiminates the interpreter's instruction decoding overhead. Since we can't access or manipulate the JavaScript stack, we might want that compiler to inline as much as possible, but keep the call sequence flat so we can return to the browser at any time. Even better (but potentially more complicated) is actually using the JavaScript stack, just like Eliot's Stack VM uses the C stack. I have done some advanced JIT mockups. To make BitBlt fast, we could probably use WASM or even WebGL.
To make SqueakJS useful beyond running existing Squeak images, we should use the JavaScript bridge to write a native HTML UI which would certainly be much faster than BitBlt (Craig Latta has done some interesting work towards that in Caffeine).
Better Networking would be interesting, too. The SocketPlugin currently does allows HTTP(S) requests and WebSockets. How about implementing low level Socket support based on HTTP-tunneling? The VM can run in a WebWorker. How about parallelizing the VM with WebWorkers?
Also interesting would be wrapping it in a native app, maybe via Electron similar to Sugarizer, which uses SqueakJS to run Etoys.
There's a gazillion exciting things to do :)
-- Vanessa Freudenberg (codefrau)
2025年05月04日: 1.3.3 minor FFI, OpenGL, and other fixes/improvements
2025年04月06日: 1.3.2 use our own CORS proxy, add welcome=false option, minor fixes
2025年03月29日: 1.3.1 add 'w', 'h', 'embedded' canvas options, minor fixes
2025年03月28日: 1.3.0 add OpenGL support, canvas is optional, fix socket plugin bug
2025年02月19日: 1.2.4 fix isAssociation for JS Bridge, optimize loading image with many objects
2024年09月28日: 1.2.3 fix primitiveInputSemaphore, fix iOS keyboard
2024年06月22日: 1.2.2 make copy/paste work on mobile
2024年05月27日: 1.2.1 add virtual cmd button, fix touch events
2024年03月25日: 1.2.0 add FFI and MIDI plugins, JIT for Sista bytecodes, JPEG write prim, fix keyboard input, copy/paste, scroll wheel, highdpi, allow ES6 in source
2023年11月24日: 1.1.2 fixed BitBlt bug (symptom reported 9 years ago, thanks to Agustin Martinez for narrowing it down), add object pinning, support keyboard in ancient Scratch images
2023年10月24日: 1.1.1 workarounds for Cuis 6
2023年10月23日: 1.1.0 implement Etoys project saving (image segment export), drag-n-drop directories
2023年09月30日: 1.0.6 fixes
2022年11月19日: 1.0.5 fixes, add highdpi mode, add image format for Squeak 6
2021年05月31日: 1.0.4 fixes
2021年03月21日: 1.0.3 headless fixes (Erik Stel); fixes object-as-method
2021年02月07日: 1.0.2 new one-way become prim (Christoph Tiede); JIT-compile Array at:/at:put:
2021年01月05日: 1.0.1 fixes some primitives to properly pop the stack
2020年12月20日: 1.0 supports 64 bits and Sista
2020年06月20日: renamed "master" branch to "main"
2020年06月20日: 0.9.9 JSBridge additions (Bill Burdick), fixes
2020年04月08日: renamed github account to "codefrau"
2020年01月26日: 0.9.8 split into modules (Erik Stel), fixes
2019年01月03日: 0.9.7 minor fixes
2018年03月13日: 0.9.6 minor fixes
2016年11月08日: 0.9.5 more fixes
2016年10月20日: 0.9.4 fixes
2016年09月08日: 0.9.3 add partial GC (5x faster become / allInstances)
2016年08月25日: 0.9.2 add keyboard on iOS
2016年08月03日: 0.9.1 fixes
2016年07月29日: 0.9 Spur support, stdout, SpeechPlugin, zipped images
2016年06月28日: 0.8.3 add SocketPlugin for http/https connections
2016年04月07日: 0.8.2 better touch handling, debugging, CORS, lint
2016年01月08日: 0.8.1 windows keyboard fixes, 'new' operator fixed
2015年11月24日: 0.8 minor fixes
2015年08月13日: 0.7.9 make work on iOS again
2015年07月18日: 0.7.8 fix keyboard
2015年06月09日: 0.7.7 fix thisContext
2015年04月27日: 0.7.6 revert JIT, minor fixes
2015年04月14日: 0.7.5 JIT optimizations by HPI students (reverted in 0.7.6)
2015年02月18日: 0.7.4 make pre-release image work
2015年01月30日: 0.7.3 JSBridge: fix closure callbacks
2015年01月25日: 0.7.2 JSBridge: add asJSObject
2014年12月22日: 0.7.1 cursor shapes
2014年12月04日: 0.7 support finalization of weak references
2014年11月28日: 0.6.8 JSBridge with callbacks
2014年11月20日: 0.6.7 implement JavaScriptPlugin
2014年11月18日: 0.6.6 implement DropPlugin
2014年11月14日: 0.6.5 add generated Balloon2D plugin
2014年11月06日: 0.6.4 add generic run page
2014年10月28日: 0.6.3 pass options via URL
2014年10月27日: add JPEG plugin
2014年10月25日: add template files
2014年10月23日: 0.6.2 fixes
2014年10月21日: 0.6.1 add image segment loading
2014年10月18日: 0.6 move squeak.js out of lib dir
2014年10月13日: 0.5.9 microphone support
2014年10月09日: 0.5.8 fixes
2014年10月07日: 0.5.7 even more plugins generated
2014年10月07日: 0.5.6 add quitSqueak and onQuit
2014年10月07日: 0.5.5 generated ScratchPlugin
2014年10月06日: 0.5.4 replace BitBltPlugin by generated
2014年10月06日: 0.5.3 SoundGenerationPlugin, Matrix2x3Plugin, FloatArrayPlugin
2014年10月05日: ZipPlugin
2014年10月04日: MiscPrimitivePlugin
2014年10月03日: VMMakerJS generates LargeIntegersPlugin
2014年09月30日: 0.5.2 more JIT
2014年09月28日: 0.5.1 JIT fixes
2014年09月26日: 0.5 add JIT compiler
2014年09月22日: v8 optimizations
2014年09月20日: 0.4.6 sound output support
2014年09月13日: 0.4.5 clipboartd fixes
2014年09月12日: 0.4.4 cut/copy/paste in stand-alone
2014年09月09日: 0.4.3 some scratch prims
2014年09月09日: 0.4.2 idle fixes
2014年09月05日: 0.4.1 scratch fixes
2014年09月04日: 0.4.0 runs scratch
2014年08月31日: switch old/new primitives
2014年08月27日: event-based input
2014年08月21日: exception handling
2014年07月25日: 0.3.3 fullscreen support
2014年07月18日: 0.3.2 benchmarking (timfel)
2014年07月18日: 0.3.1 deferred display
2014年07月16日: 0.3.0 closure support
2014年07月14日: 0.2.3 IE optimization (timfel)
2014年07月11日: 0.2.2 drag-n-drop
2014年07月07日: 0.2.1 fixes for IE11 (timfel)
2014年07月04日: 0.2 runs Etoys
2014年06月27日: Balloon2D (krono)
2014年06月03日: stand-alone version
2014年05月29日: 0.1 added version number
2014年05月27日: WarpBlt
2014年05月07日: image saving
2014年04月23日: file support
2013年12月20日: public release
2013年12月14日: colored bitblt
2013年12月03日: first pixels on screen
2013年11月29日: GC
2013年11月22日: runs 43 byte codes and 8 sends successfully
2013年11月07日: initial commit