Skip to content

Global Variables and Permissions

These variables are automatically set when your app is launched:

VariableTypeDescription
APP_DIRstringAbsolute path to your app’s directory (e.g., "/apps/hello")
APP_NAMEstringName of your app as defined in app.json
APP_IDstringReverse-DNS app identifier from app.json (e.g., "net.picodeck.hello")
APP_REQUIREMENTStableGranted requirements as boolean fields (see App Requirements)

These globals are copies for your convenience. The OS enforces the sandbox and the per-app stores from its own record of the running app, so changing them grants nothing.


Apps can request elevated requirements via the requirements array in app.json:

{
"requirements": ["root-filesystem"]
}
RequirementDescription
filesystemDefault sandbox access: read /apps/<appname>/, read/write /data/<appid>/
root-filesystemFull SD card read/write access (bypasses sandbox)
httpApp needs WiFi/network connectivity (WiFi stays connected after boot time sync)
audioApp needs audio output
clipboardReserved for future use
sysconfigpicocalc.sysconfig (system-wide config) is registered; without it picocalc.sysconfig is nil. get("wifi_pass") always returns nil (write-only)
system-updatepicocalc.sys.applyUpdate is registered — only for OS apps (id net.picodeck.updater / net.picodeck.store, or an app under /system/)

The APP_REQUIREMENTS global is a table with boolean fields — .root_filesystem, .http, .audio. sysconfig and system-update have no field: test picocalc.sysconfig ~= nil / picocalc.sys.applyUpdate ~= nil.

if APP_REQUIREMENTS.root_filesystem then
-- App has full filesystem access
local entries = picocalc.fs.listDir("/system")
else
-- Restricted to sandbox
local path = picocalc.fs.appPath("save.json")
end

Without root-filesystem, the filesystem API restricts access to:

  • Read: /apps/<appname>/ (your app’s directory) and /system/lib/
  • Read/Write: /data/<appid>/ (auto-created app data directory)

Relative paths and any .. are refused. The same check guards the image, font and zip loaders, the sound loaders (sound.sample/sampleplayer paths, sample:load, sample:save, fileplayer:load, mp3player:load), modplayer:load, video:load and crypto.sha256File; a refused call returns false, "access denied" (or nil, "access denied"). fs.browse(start) falls back to your data directory when start is not readable.

The id in app.json names your data directory (/data/<id>), so it must be 1-79 characters of [A-Za-z0-9._-], with no .. and no trailing .. It is compared case-insensitively (the SD card is), so com.Example.App and com.example.app share one directory. The launcher refuses an app with an invalid id (on-screen reason and an /system/error.log entry). A missing id defaults to local.<dir>.

Use picocalc.fs.appPath("filename") to get paths within your app’s data directory.