Imports and Package Management (upcoming)
Available in version 1.1.72 (not yet live).
Use standard JavaScript imports like import dayjs from "[email protected]" or use the zw API zw.import() for custom options to install (if needed) and import packages during a TaskBot run. ZeroWork installs missing packages and makes them available to your code.
Manage packages with zw.packages.list(), zw.packages.uninstall(), and zw.packages.uninstallAll().
API zw.import(), zw.packages.*
// @zw-run-locally
// Use desktop automation in ZeroWork
import { execSync } from "child_process";
import { keyboard } from "@computer-use/nut-js";
// Open an editor depending on OS
if (process.platform === "win32") {
execSync("start notepad");
} else if (process.platform === "darwin") {
execSync(`osascript -e 'tell application "TextEdit" to activate' -e 'tell application "TextEdit" to make new document'`);
} else {
execSync("gedit || xed || kate || nano", { shell: "/bin/bash" });
}
// Wait briefly for the editor window to appear
await zw.delay({ min: 2_000 });
// Type into the editor
await keyboard.type("Hello from ZeroWork desktop automation!");1. Imports
Standard Imports
You can use standard ESM or CommonJS syntax. Any such import installs the package if needed, then loads it.
Notes
Installed packages are available to any TaskBot by default. To scope per TaskBot, use
zw.import()with{ isolate: true }(see details further below).If a package isnβt used for one week, it's removed automatically. To change this window or prevent automatic uninstall, use
zw.import()withuninstallIfUnusedFor(see details further below).Subpaths like
"lodash/chunk"and Git repositories are supported.You can disable auto-imports by adding a comment
// @zw-disable-auto-import
Imports with zw.import()
zw.import() Use zw.import() when you need options or want to import several packages at once.
At a Glance
async
await zw.import(options: ImportOptions, pkg: string | string[] | { [key: string]: string })β installs if needed and returns the loaded module(s)
Examples
Single package with options
Multiple packages as an array
Named mapping as an object
Installing from Git (HTTPS only)
Use default options by passing an empty object {}
Import Option Details
uninstallIfUnusedFor(default:168) Defaults to 168 hours (one week). Set tonullto keep the package on the device indefinitely.isolate(default:false) Whentrue, the package is scoped to this TaskBot only and isnβt visible in other TaskBots. Useful when different TaskBots need different versions of the same package. Note: If the TaskBot is deleted, the package isnβt removed automatically; you can manage it later withzw.packages.*(see details further below).preferDefault(default:true) β advanced Returnsmodule.defaultwhen present (otherwise the module object). This only changes the return shape; it doesnβt affect how the module is resolved.
Supported Package Inputs
You can pass any of the following to zw.import() as the second argument.
String
"lodash","[email protected]","lodash/chunk","https://github.com/user/repo.git#main"or"git+https://github.com/user/repo.git#main"Array of strings
["[email protected]", "[email protected]"]Object mapping
{ util: "[email protected]", time: "[email protected]" }
Invalid inputs that are rejected
Tarball URLs, local file paths, and directories
Non-HTTPS Git URLs
Special Package Types
Built-in Packages
These packages are pre-bundled and resolve without installation.
Node core modules such as
fs,os, etc.axiospinned to^1.6.6playwrightpinned to^1.45.0
They donβt appear in zw.packages.list(), and you canβt change their versions or uninstall them.
Pure ESM Packages
ZeroWork isnβt pure ESM yet. Pure ESM packages arenβt supported and will throw an error similar to:
This package appears to be pure ESM. Pure ESM packages are currently not supported. To confirm, check the package documentation.
Workarounds for pure ESM packages
Use a maintained non-ESM fork if available. For example,
cacheable-lookupis a pure ESM module but a maintained fork is available:@esm2cjs/cacheable-lookup.Pin a non-ESM version if the project provides one. For example, the latest
chalkversion is pure ESM but its documentation recommends pinning to v4chalk@4for a CommonJS build.If the package is pure ESM with no CommonJS fork or version, you will have to find an alternative.
Native Packages
Packages that include native code (C/C++ or other system-level bindings) may not work reliably. They often require a compatible Node version, build tools, or system libraries. This typically affects modules that talk directly to the operating system or hardware β for example node-window-manager, robotjs, or ffi-napi. Advanced users with the right setup might get them working, but they arenβt guaranteed to install or run on all systems.
Reusing References
Import once and reuse the reference, as is generally best practice. The package wonβt reinstall if itβs already installed, but package parsing and resolution still add overhead.
2. Package Management
At a Glance
async
await zw.packages.list()β returnsstring[]of package IDs.async
await zw.packages.uninstall(id: string)β removes one.async
await zw.packages.uninstallAll()β removes all user-managed packages.
Whatβs a Package ID?
A package ID uniquely identifies an installed package instance. Itβs an opaque string made of an optional isolation prefix (<taskbotId>_), a lower-cased, sanitized package name, @, and a version tag (<semver>, latest, git, or a commit hash). It may differ from your original import string (subpaths arenβt included; characters are normalized).
Examples
Use these IDs with zw.packages.uninstall(id).
Examples
List packages
Uninstall by package name/version
Uninstall all for a specific TaskBot
Uninstall all
3. Local and Browser Execution
Package installation and management run locally only. Standard import/require, zw.import(), and zw.packages.* are supported only when the Write JS block runs outside the browser context. Enable the Run locally checkbox in the block UI, or add the comment // @zw-run-locally.
You can still use imported packages in the browser by exposing functions from a local block (see below).
How to Use Imported Packages in the Browser
Import locally in one block, expose a function, then call it from a later block that runs in the browser.
Functions exposed via context.exposeFunction() always become asynchronous in the browser, even if they were defined as synchronous. Always call them with await.
Last updated
Was this helpful?