With GhostESP v2.1, I wanted to build on top of v2.0: native SD apps, asset packs, the App Gallery, all of it. This time around I focused on three things I had wanted to tackle for a while: NFC, scripting, and OTA updates. Beyond that, it's mostly polish on everything v2.0 started.

Cloud Store

One of the bigger additions is the Cloud Store in the Apps gallery. You can browse and install apps, GhostScript scripts, and asset packs directly on the device from the GitHub catalogs.

Honestly, it's mostly about convenience. I hate taking my SD card out, putting it into my PC, copying files over, putting it back in the device, and then hoping I did not forget something. Now you can download what you want on-device, watch the progress bar, and get back to using it.

OTA Updates

OTA updates have been in the works for a while, and they ended up being a lot more complicated than I expected.

GhostESP supports a lot of different boards, with different flash sizes and partition layouts. Some older board configs also don't reflect the actual flash size fitted to the device, because that was never set correctly when the config was first made. Safe OTA needs room for a second firmware image, and on boards that are already tight on flash, that gets difficult fast. Flash space in general is something we're running low on across a few configs, and doing OTA safely means budgeting for roughly double the application's flash size, not just squeezing the update in wherever there's room.

The Banshee C5 was the worst case. It has 8 MB of flash, but about 1.1 MB of that is already reserved for native SD apps running through XIP. XIP matters on the C5 because without it, apps can't execute from external RAM, which puts a hard ceiling on how big native apps can be. There just wasn't room left for a second firmware image the normal way.

So I ended up writing a separate application firmware just for OTA. The Banshee reboots into it, that firmware connects to the saved Wi-Fi network, downloads the new image, flashes the correct firmware partition, then reboots back into GhostESP proper.

There's also GhostLink OTA, so a primary device can download an update and safely flash a paired peer chip, and offline installs from the SD card if you'd rather not use Wi-Fi. Getting the progress bar working was a small thing, but it was the point where the whole system finally felt done, and downloads ended up faster than I expected.

GhostScript

v2.1 also adds GhostScript, a sandboxed Lua 5.4 runtime for running scripts off the SD card, including on devices without PSRAM. There's a script browser, CLI commands, scoped storage, permissions, and support for longer-running scripts that cooperate with the rest of the system instead of blocking it.

Native SD apps are still the right call when you need performance or deeper integration. GhostScript is for everything else, a lighter way to build and experiment without writing a full native app.

NFC

NFC got real attention this release. v2.1 adds support for the ST25R3916 and ST25R3916B over SPI or I2C alongside the existing PN532 support, with a backend selector in the UI and CLI so you can pick which hardware GhostESP talks to.

On top of that: MIFARE Classic nested recovery, PicoPass/iCLASS reads, NDEF creation, NTAG metadata, DESFire summaries, and general cleanup across the NFC menus. Still more I want to do here, but it's a much better foundation now.

Everything Else

There's plenty more in v2.1 beyond the headline stuff: new Wi-Fi tools, a QR Generator native SD app, SDK improvements, new infrared protocol support, a more capable headless CLI, better wardriving behavior, and a round of UI and memory fixes across a lot of boards.

That's v2.1: install things without pulling your SD card, update firmware without a manual reflash, write a script instead of a full app, and more NFC hardware working out of the box.

Full details in the v2.1 changelog.