Limits & FAQ
Compilation
- Every app is bundled by the in-browser compiler, which supports Node built-ins in tiers (the
node:prefix works the same way):- Browser polyfills that work normally:
process/events/util/stream/url/querystring/assert/string_decoderand similar - Local implementations:
path,bufferandtimersare fully usable;cryptocovers part of the API (Web Crypto,randomBytes,pbkdf2, andcreateHashfor md5 / sha1 / sha224 / sha256 — noscrypt);zlibsupports async gzip / deflate only (*Sync, Brotli and stream APIs throw when called);fs/fs/promisessupport async APIs only and work only in temporary terminalrunscripts — in app source the calls are rejected withWORKSPACE_LEASE_REQUIRED - Importable, but every call throws (with an
[lf-node-shim]prefix):http/https/net/tls/dns/os/readline/ttyand similar - Compile errors:
child_process/cluster/worker_threads/vm/v8/inspector/module/repl
- Browser polyfills that work normally:
- Use standard ESM
importfor local modules.@requireonly accepts built-in ids; a local file (e.g.// @require ./lib.js) fails the compile - The plugin build reads
@requirefrom the entry file only: built-in libraries used by components or utility files must be declared in the entry too. A@requirein a non-entry file's header only applies when that file is run directly from the terminal (the editor shows a Warning) - Import Vue normally (
import { createApp } from "vue"); it is no longer a built-in runtime alias
Runtime
LFHttprejects only the local PluginX client port (41720on any loopback form),chrome-extension://,file://, and non-http(s) targets, and re-checks the final address after redirects. Only the literal hostname is checked. The local client is reachable only throughLFHttp.client. The target domain's existing cookies are attached by default; you can also setheaders.Cookieexplicitly (it replaces the browser's cookies entirely). Browser-reserved headers such asReferer/User-Agentare written at the network layer — seeheaderOverrideson the responseLFNetworkis available in saved bundles, the liveDebug USER_SCRIPT path, andrun --tabMAIN-world scripts (via the network relay bridge); using it directly requires an explicit// @require network(@require domis not enough)LFRuntime.readFile/writeFile/execTerminalCommandcan only be called directly from temporary terminalrunscripts (run/run -c/run --tab/run --target background). In app source (liveDebug, enabled / installed, background apps) a direct call fails the compile: register a command withLFRuntime.cli.register({ workspace: ['read' | 'write' | 'exec'] })and usectx.workspace.readFile/writeFile/execin its handler. The lease only lasts for thatplugincmd call- Local command execution, local file access and CLI registry requests are accepted only from the PluginX editor page; when an app (page-injected, background, or USER_SCRIPT world) sends these extension messages directly they are rejected with
EACCES_PERMISSION LFStorestores values as JSON: a value containing aMap/Set/ function /Symbol/BigInt/ circular reference makessetthrow with the offending path (e.g.at value.cache); convert it to plain JSON data first- Intercepting page requests with
LFRuntime.network.onResponse/interceptRequest/interceptResponserequires an@interceptdeclaration in the entry header; without it "Compile" fails (liveDebug andrun --tabskip this check)
IDE
- Saving (Ctrl+S) only stores the sources; clicking "Compile" (which saves first) compiles and updates the registered artifact. Until you compile, enabled apps and reloaded pages keep running the previous build
- Create files/folders from the file-tree header, rename or delete from the context menu, or use
mv/rmin the terminal; renaming or moving the entry file keeps the entry setting in sync - First-time npm dependency compiles download from the network; later ones hit the IndexedDB cache (see "System Info")
- liveDebug keys page lifecycle to the browser documentId: SPA modals and
history.pushStateURL changes that retain the document do not reinject or unregister CLI commands. Only a full navigation/reload with a new document destroys the old USER_SCRIPT and interrupts in-flightplugincmdcalls; registrations recover automatically after load, while the interrupted call must be retried afterinjectionHealthy: true - If named USER_SCRIPT-world messaging configuration fails, liveDebug retries three times and then stops before injection instead of running a partial instance without LFStore/LFUser/LFNetwork/CLI support. Run
liveDebug reloadafter the environment recovers
Permissions
Installed apps only run once the browser grants the extension userScripts capability (the "Allow User Scripts" switch or Developer mode). Until then the app manager shows a guidance banner — follow it, then click "Re-check Permission".