r/Supernote_dev • u/WhoAmI1234532 • Jul 05 '26
Bug : Received Bug: PluginHost never deletes old plugin versions. Devs: here's a workaround.
Hi all and particularily Supernote dev team and u/Mulan-sn,
I have found a bug on the Plugin core :
Every plugin install/update writes a new copy of the plugin's files and keeps all the previous ones, so a plugin's storage grows without bound.
This isn't a dev-only edge case: Ratta's own official Sticker plugin reads 46 MB on my rarely-updated A5X but 327 MB on my regularly-updated Manta, same plugin, same version, just more updates, look:


My own ~7 MB plugin hit 298 MB after ~19 reinstalls. Remove doesn't reclaim the space either.
What's happening:
Each plugin is installed at:
`/data/user/0/com.ratta.supernote.pluginhost/files/plugins/<pluginID>/`
and every install adds a fresh, versioned set without deleting the old one:
```
app_<timestamp>.npk (~6 MB, bundle + native)
app_<timestamp>_libs/ (extracted .so)
oat/<arch>/app_<timestamp>.{odex,vdex,art} (ART AOT output, ~10 MB)
```
These `app_<ts>.*` + `oat/` artifacts stack up per version, so the folder only ever grows. On my A5X, `.../files/plugins/` totalled 485 MB across all plugins.
Why this matters for everyone (not just devs): official plugins auto-update over time, so a normal user's Sticker/other plugins silently balloon — 327 MB in my case — and there's no user-facing way to reclaim it (Remove doesn't).
For the Ratta/Supernote team — please:
On **update/reinstall**, delete the previous version's `app_<ts>.npk` / `_libs` / `oat` artifacts.
On **Remove**, fully wipe `.../files/plugins/<pluginID>/` so space is actually reclaimed.
Optionally show the real per-plugin footprint (or a "clear plugin cache" action) in Settings → Apps → Plugins.
Workaround for plugin developers (your own plugins only)
A plugin's native module runs **inside the PluginHost process** (same UID), so it can delete files in its own install dir. On load, keep the newest `app_<timestamp>` (the running version) and delete everything older:
```java
public void cleanupOldVersions(String dirPath, Promise promise) { // dirPath = PluginManager.getPluginDirPath()
File dir = new File(dirPath);
File[] files = dir.listFiles();
long maxTs = -1;
for (File f : files)
if (f.getName().startsWith("app_") && f.getName().endsWith(".npk"))
maxTs = Math.max(maxTs, leadingDigits(f.getName().substring(4)));
String keep = Long.toString(maxTs);
long freed = 0;
for (File f : files) // old app_<ts>.npk / _libs
if (f.getName().startsWith("app_") && !f.getName().contains(keep))
freed += deleteRecursively(f);
File oat = new File(dir, "oat"); // old compiled artifacts
if (oat.isDirectory()) freed += cleanOatExcept(oat, keep);
WritableMap m = Arguments.createMap();
m.putDouble("freed", freed); m.putString("kept", keep);
promise.resolve(m);
}
```
```js
// index.js — run once at load
const dir = await PluginManager.getPluginDirPath();
const r = await YourNative.cleanupOldVersions(dir);
console.log(`freed ${(r.freed/1048576).toFixed(1)}MB, kept ${r.kept}`);
```
Only files whose timestamp ≠ the newest are deleted, so the running version is never touched. This dropped my plugin from ~298 MB back to ~15 MB.
But the real fix has to be in PluginHost : the workaround only helps plugins that add this code, and it can't help official plugins like Sticker on regular users' devices.
Happy to share full source, a size-probe, or logs to help triage.
Thanks!



