Dynamic Core Module Reference in TiddlyWiki Plugins
The Problem
When overriding a core widget (e.g. text.js), you often need the original version as a sub-widget or fallback. The conventional approach is to maintain a separate copy of the original — but this breaks silently whenever core is upgraded.
The Solution
TiddlyWiki’s core is itself a plugin. All original module source code is preserved in $tw.wiki.getPluginInfo("$:/core").tiddlers, even after being overridden. You can retrieve that source at runtime and re-execute it under a new name.
(function() {
var pluginInfo = $tw.wiki.getPluginInfo("$:/core");
var shadowSource = pluginInfo.tiddlers["$:/core/modules/widgets/text.js"].text;
var twRequire = function(title) {
return $tw.modules.titles[title] && $tw.modules.titles[title].exports;
};
var coreExports = {};
new Function("exports", "require", shadowSource)(coreExports, twRequire);
// Register the original "text" widget under a new alias
exports["plain-text"] = coreExports.text;
})();
Place this IIFE at the top of your overriding module. The original widget is now available as plain-text for internal use, while your custom logic is exported as text.
Why This Works
getPluginInfo("$:/core").tiddlersalways contains the original shadow source, regardless of any overrides applied on topnew Function("exports", "require", source)re-executes the module in isolation, producing a freshexportsobject- The result is registered into the widget system alongside your override — no separate file needed
Verified Output
// plain-text.js (emptied) → exports: []
// text.js (override) → exports: ["plain-text", "text"] ✓
Advantages over Conventional Approaches
| Approach | Upgrade-safe? | Self-contained? |
|---|---|---|
| Copy original into a separate file | ||
| Shadow override only | ||
| Mod-Loader (boot-time patch) | ||
| This approach (runtime re-execution) |
Caveats
- The lightweight
twRequireshown above only resolves already-loaded modules. If the original module has deeprequiredependencies at execution time, you may need to extend it. - This relies on
getPluginInfobeing available at module load time, which is the case for all standardmodule-type: widgetmodules in TiddlyWiki 5. - This is not a silver bullet. If a future core upgrade significantly changes the internal structure or API of the original module, your override will still break — just as it would with a manually maintained copy. The real benefit is simply one less file to maintain, and the guarantee that you’re always executing the latest core source rather than a stale snapshot.
*Discovered while building the Freelinks plugin. Tested on TiddlyWiki v5.4.1-prerelease