CreateJS Modernization?

CreateJS was originally built to handle browser inconsistencies during the fragmented era of web development (2010-2015). Now in 2026, browsers are standardized and many legacy workarounds are no longer needed. This document outlines a comprehensive plan to modernize the CreateJS suite (EaselJS, TweenJS, SoundJS, PreloadJS) while maintaining API compatibility.

I employed AI to help review the legacy codebase to eliminate code that is now redundant. I think there are some very compelling suggestions which lead to a 20%+ reduction in code.

My Proposed Goals

  • Remove ~5,000+ lines of dead/legacy code
  • Reduce bundle sizes by 20%+
  • Improve performance by eliminating polyfills

Proposed Browser Support

Browser Minimum Version
Chrome 66+ (Apr 2018)
Firefox 60+ (May 2018)
Safari 13+ (Sep 2019)
Edge 79+ Chromium (Jan 2020)

Phase 1: Remove Dead Code (Critical Priority)

1.1 Flash Audio Plugin Removal (SoundJS)

Status: Flash Player was discontinued January 12, 2021

Files to Delete:

SoundJS/src/soundjs/flashaudio/
β”œβ”€β”€ FlashAudioPlugin.js      (~460 lines)
β”œβ”€β”€ FlashAudioLoader.js      (~200 lines)
β”œβ”€β”€ FlashAudioSoundInstance.js (~350 lines)
└── FlashAudioPlugin.swf

SoundJS/src/swfobject.js     (~500 lines)

Impact: ~1,500 lines removed

Migration Notes:

  • Users relying on Flash fallback should migrate to WebAudio or HTMLAudio
  • No code changes needed for users already using WebAudioPlugin

1.2 IE/ActiveX Fallbacks Removal (PreloadJS)

File: PreloadJS/src/preloadjs/net/XHRRequest.js

Remove:

// Lines ~460-480: XDomainRequest (IE8-9 cross-domain)
if (crossdomain && req.withCredentials === undefined && window.XDomainRequest) {
    req = new XDomainRequest();
}

// Lines ~470-480: ActiveXObject fallback (IE6-9)
for (var i = 0, l = s.ACTIVEX_VERSIONS.length; i < l; i++) {
    var axVersion = s.ACTIVEX_VERSIONS[i];
    try {
        req = new ActiveXObject(axVersion);
        break;
    } catch (e) {}
}

Also remove the ACTIVEX_VERSIONS constant:

s.ACTIVEX_VERSIONS = [
    "MSXML2.XMLHttp.6.0",
    "MSXML2.XMLHttp.5.0",
    // ...
];

File: PreloadJS/src/preloadjs/utils/DataUtils.js

Remove:

// Lines ~67-71: ActiveXObject XML parsing fallback
try {
    xml = new ActiveXObject("Microsoft.XMLDOM");
    xml.async = false;
    xml.loadXML(text);
} catch (e) {
    xml = null;
}

Impact: ~100 lines removed


1.3 BlobBuilder Fallback Removal (PreloadJS)

File: PreloadJS/src/preloadjs/net/XHRRequest.js

Remove:

// Lines ~354-363: BlobBuilder was deprecated in 2012
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || 
                     window.MozBlobBuilder || window.MSBlobBuilder;
if (e.name === 'TypeError' && window.BlobBuilder) {
    var builder = new BlobBuilder();
    builder.append(this._response);
    this._response = builder.getBlob();
}

Replace with: Simple Blob constructor (universally supported)

this._response = new Blob([this._response]);

Impact: ~15 lines removed


1.4 Deprecated Web Audio API Methods (SoundJS)

File: SoundJS/src/soundjs/webaudio/WebAudioPlugin.js

Remove entire _compatibilitySetUp method:

// Lines ~386-400: These deprecated methods haven't been needed since 2014
s._compatibilitySetUp = function() {
    s._panningModel = "equalpower";
    if (s.context.createGain) { return; }
    
    // These are all obsolete:
    s.context.createGain = s.context.createGainNode;
    audioNode.__proto__.start = audioNode.__proto__.noteGrainOn;
    audioNode.__proto__.stop = audioNode.__proto__.noteOff;
    s._panningModel = 0;
};

Impact: ~20 lines removed


1.5 Touch Event Simplification (EaselJS)

File: EaselJS/src/easeljs/ui/Touch.js

Proposed Changes:

  • Remove iOS Touch Events (touchstart, touchmove, touchend, touchcancel)
  • Remove MSPointerEvents (MSPointerDown, MSPointerMove, etc.)
  • Simplify to Pointer Events only (pointerdown, pointermove, pointerup, pointercancel)
  • Update isSupported() to check only for window.PointerEvent

Impact: 315 β†’ 232 lines (83 lines removed, 26% reduction)

Phase 2: Remove Vendor Prefixes (Medium Priority)

2.1 requestAnimationFrame Prefixes

Files:

  • EaselJS/src/createjs/utils/Ticker.js
  • TweenJS/src/createjs/utils/Ticker.js

Before:

var f = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || 
        window.mozCancelAnimationFrame || window.oCancelAnimationFrame || 
        window.msCancelAnimationFrame;

var f = window.requestAnimationFrame || window.webkitRequestAnimationFrame || 
        window.mozRequestAnimationFrame || window.oRequestAnimationFrame || 
        window.msRequestAnimationFrame;

After:

var f = window.cancelAnimationFrame;
var f = window.requestAnimationFrame;

Note: Universally supported since 2012


2.2 AudioContext Prefix (SoundJS)

File: SoundJS/src/soundjs/webaudio/WebAudioPlugin.js

Before:

var AudioCtor = (window.AudioContext || window.webkitAudioContext);

After:

var AudioCtor = window.AudioContext;

Note: Safari dropped webkit prefix in v14.1 (April 2021)


2.3 CSS Transform Prefixes (EaselJS, PreloadJS)

File: EaselJS/src/easeljs/display/DOMElement.js

Before:

style.transformOrigin = style.WebkitTransformOrigin = style.msTransformOrigin = 
                        style.MozTransformOrigin = style.OTransformOrigin = "0% 0%";

style.transform = style.WebkitTransform = style.OTransform = 
                  style.msTransform = str +","+ (mtx.ty+0.5|0) +")";
style.MozTransform = str +"px,"+ (mtx.ty+0.5|0) +"px)";

After:

style.transformOrigin = "0% 0%";
style.transform = str + "," + (mtx.ty + 0.5 | 0) + ")";

Note: Unprefixed transforms supported since 2013


2.4 WebGL Context Prefix (EaselJS)

File: EaselJS/src/easeljs/display/StageGL.js

Before:

gl = canvas.getContext("webgl", options) || canvas.getContext("experimental-webgl", options);

After:

gl = canvas.getContext("webgl", options);

Optional Enhancement: Consider adding WebGL2 support:

gl = canvas.getContext("webgl2", options) || canvas.getContext("webgl", options);

Phase 3: Remove Legacy Utilities (Medium Priority)

3.1 Array.indexOf Polyfill (EaselJS)

File: EaselJS/src/createjs/utils/indexOf.js

Remove entire file and usages:

// This file can be deleted - Array.prototype.indexOf supported since IE9
createjs.indexOf = function (array, searchElement){
    for (var i = 0,l=array.length; i < l; i++) {
        if (searchElement === array[i]) {
            return i;
        }
    }
    return -1;
};

Replace usages with:

array.indexOf(searchElement)

3.2 Browser Detection Removal (SoundJS)

File: SoundJS/src/createjs/utils/BrowserDetect.js

Review and remove unnecessary checks:

// These are generally anti-patterns in 2026
BrowserDetect.isWindowPhone = ...  // Windows Phone discontinued 2017
BrowserDetect.isBlackberry = ...   // BlackBerry OS discontinued 2013
BrowserDetect.isOpera = ...        // Opera uses Chromium since 2013

Replace with: Feature detection where needed


3.3 iOS Sample Rate Workaround (SoundJS)

File: SoundJS/src/soundjs/webaudio/WebAudioPlugin.js

Review if still needed:

// Lines ~360-370: iOS sample rate fix
if (/(iPhone|iPad)/i.test(navigator.userAgent)
        && context.sampleRate !== s.DEFAULT_SAMPLE_RATE) {
    // workaround...
}

Status: Test on modern iOS (15+) to verify if still required. This was a bug in iOS 6-9.

1 Like

Hi Chris - is all this at your initiative? Just checking to make sure it is not a repost from the CreateJS GitHub, for instance.

Yes, I’ve been busy today!

lol - yes. I guess it would not hurt to see if we can adjust these things on a test version of our createjs. If you want to be busier, you could try. lol - how's that ;-). Maybe we will get in the mood too. But let us know if you want to have a first go.

I know that you have a forked and flattened release version on GitHub at danzen/createjs. The original version on GitHub is out of date isn’t it.

So, where is best to get involved?

I posted the above as a discussion starter. Do you have a view on the minimum browser support?

Let's work with our current version of CreateJS. https://zimjs.org/cdn/1.5/createjs_doc.js - this is the one on our GitHub. Yes - the CreateJS GitHub version is not up-to-date for our needs - it is missing TextureActive, Monitor, and probably other things. On the other hand... it might be nice for them to have a version of this as well... but I can take out the monitor and texture active code fairly easily. So let's work on our version 1.5.

The proposed browser cut-off seems good. If people need to support older browsers, perhaps we can provide a way for that to happen.

Okay, so the file has been flattened and it's not just a build artifact then? That's what put me off from looking into contributing before - I thought you had a secret fork which you compiled from.

Is the ZIM source also a single file and up to date on your Github danzen/zimjs page?

When we do drop support for old browsers, which people shouldn't be using any more, we should increment the version number to 2.0. I'm not suggesting we change the API with this effort, so if there are any future changes, like you say they could be patched back into 1.5.

Agreed - version 2. Yes, we work on a flattened file - for ZIM too. And yes, up-to-date for CreateJS and for ZIM within a minor change or two on the github.

2 Likes

The major saving I proposed (based on the CreateJS repo), removing the Flash Audio Plugin, has already been done in 1.5 so we won't be reducing the code as much as my goal!

Did you notice it if was in our createjs code or not? I think we stemmed from the latest on their repository as we started updating their repository too - although it has probably been a couple years since a change there.

The Flash Audio Plugin that I'd earmarked as a huge saving has already been removed from our CreateJS yes. I have submitted a pull request to you with my proposed 'modernization' changes.

I would have liked to use the standard window.scrollX and window.scrollY, but ZIM overrides them with zim.scrollX(num, time) and zim.scrollY(num, time).

create_doc.js line 8691:

//var offX = window.scrollX; // would be nice to use window.scrollX but zim.scrollX(num, time) exists
//var offY = window.scrollY; // would be nice to use window.scrollX but zim.scrollY(num, time) exists
 
var offX = (typeof window.scrollX === 'function' ? window.scrollX() : window.scrollX);
var offY = (typeof window.scrollY === 'function' ? window.scrollY() : window.scrollY);

I'm not sure whether relying on the window.scrollX() function if it exists is acceptable in our "ZIMJS" context? I wouldn't patch this back to the original CreateJS repo.

1 Like

Just soft tested the new createjs (tentative 2.0) and so far so good. Works with TextureActive - works with sound. Dragging works.

Minified, it goes from 265k to 261k - so not that much of a difference but that difference is all in simplified code so a tidier code base with reduced legacy testing.

We have changed scrollX and scrollY to getScrollX and getScrollY.

1 Like

So glad it is working for you at first glance. I'm going to keep testing across all the devices I have. I don't have any whiteboards though.