Custom Local JavaScript transforms
Custom Local JavaScript transforms let you write small text-in/text-out scripts for formatting, cleanup, extraction, or repetitive edits that do not need AI.
They run locally: on Android they execute on-device, and in the web dashboard the Try it panel runs in your browser. Nibit stores and syncs the JavaScript source for Cloud Pro users; compiled bytecode and execution logs stay local.
Plan availability
Section titled “Plan availability”| Capability | Free | Local Pro | Cloud Pro |
|---|---|---|---|
| Use built-in local transforms | ✅ | ✅ | ✅ |
| View/copy built-in equivalent JavaScript where available | ✅ | ✅ | ✅ |
| Fork built-ins into editable custom Local JavaScript | — | ✅ | ✅ |
| Create and run custom Local JavaScript on Android | — | ✅ | ✅ |
Import/export .nibit-transform bundles on Android | — | ✅ | ✅ |
| Create, test, import/export, and sync Local JavaScript from the web dashboard | — | — | ✅ |
| Create and run custom AI prompt transforms | — | — | ✅ |
Authoring contract
Section titled “Authoring contract”Each transform defines an async function named transform:
async function transform(input, nibit) { return input.trim()}inputis the text Nibit is transforming.nibitcontains the local APIs listed below.- Return a string. Returning anything else is treated as an error.
- Throwing an error, rejecting a Promise, timing out, or returning a non-string preserves the original input.
- Source is limited to 128 KB.
Available APIs
Section titled “Available APIs”All v1 APIs are async-safe, even when the current implementation can return immediately.
nibit.clipboard.read()
Section titled “nibit.clipboard.read()”Reads the current clipboard text when available.
async function transform(input, nibit) { const clip = await nibit.clipboard.read() return `${input}\n\nClipboard: ${clip ?? ''}`}nibit.context.currentApp()
Section titled “nibit.context.currentApp()”Returns context about the current app when Nibit can provide it. In the web dashboard test runner, this comes from the Current app test field.
async function transform(input, nibit) { const app = await nibit.context.currentApp() nibit.log(`Current app: ${app ?? 'unknown'}`) return input}nibit.log() and console.*
Section titled “nibit.log() and console.*”Use logs while testing or troubleshooting. Recent logs are stored locally with execution metadata, but Nibit does not store raw input or output by default.
async function transform(input, nibit) { console.log('Starting cleanup') nibit.log(`Input length: ${input.length}`) return input.replace(/\s+/g, ' ').trim()}Examples
Section titled “Examples”Normalize whitespace
Section titled “Normalize whitespace”async function transform(input, nibit) { nibit.log('Normalizing whitespace') return input.replace(/\s+/g, ' ').trim()}Keep only email addresses
Section titled “Keep only email addresses”async function transform(input, nibit) { const emails = input.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi) ?? [] return [...new Set(emails)].join('\n')}Add a prefix to every non-empty line
Section titled “Add a prefix to every non-empty line”async function transform(input, nibit) { return input .split('\n') .map(line => line.trim()) .filter(Boolean) .map(line => `- ${line}`) .join('\n')}What is not available in v1
Section titled “What is not available in v1”Custom transforms do not get APIs for network requests, filesystem access, launching apps, or arbitrary Android/browser integration. Keep transforms focused on text processing.
Privacy and safety
Section titled “Privacy and safety”- Local JavaScript source is the canonical saved form.
- Cloud Pro sync and backups store source plus safe metadata.
- Bytecode caches are local only.
- Logs are local rolling history.
- Raw input and output are not stored in execution logs by default.
- If a transform fails, Nibit leaves the original input unchanged.