Nubu
  • Features
  • How it works
  • Pricing
  • Integrations
  • FAQ
  • Contact
  • Docs
  • Blog
  • Log in
  • Log inSign up
    Nubu

    Creative automation for teams that ship campaigns, not busywork.

    Try for free
    Product
    FeaturesNubu MotionHow it worksPricingIntegrationsFAQ
    Company
    AboutContactDocsBlogLog in
    Legal
    Privacy policyTerms of serviceData deletion
    © 2026 Bear Studios · Nubu
    Introduction
    Templates overviewInstalling Nubu BuilderAdding template compsAdding propertiesAdding footageSetting defaultsExporting your templateUploading a template
    Flows overviewAvailable nodesAdding a nodeConnecting nodesWorking with dataTemplates and outputsUsing AI nodesBuilding a creative
    CampaignsTemplatesAssetsGlossariesRendersSettings
    Connecting Meta AdsConnecting Google AdsConnecting OpenAIConnecting Gemini AI StudioConnecting Anthropic
    AI Assistant overviewPrompt examplesAssistant settings and controls
    Nubu Motion scripts: the reference
    OverviewQuick startDifferences from After EffectsDeterminism
    JavaScript supportReferences and idsProject scriptsState and timeBudgets and errorsFormatting values
    GlobalTime conversionInterpolationVector mathsRandom and noiseColour conversionOther maths
    LayerCompPropertyKeyframePathGeometryProjectComponentConsoleComponentControlExpressionControl
    The property vocabularyAnimators propertiesAudio propertiesContent propertiesContents propertiesEffects propertiesExpression controls propertiesFills propertiesInstance controls propertiesLayer propertiesLayout propertiesMasks propertiesStrokes propertiesText style propertiesRig propertiesRigging propertiesRig controllers propertiesRigging weights propertiesRigging mesh propertiesRig items propertiesRig splines propertiesRig simulation propertiesRig properties propertiesRig drivers propertiesRig draw order propertiesTransform propertiesTrim path properties
    Error codesBudgets
    Changelog
    API overviewAuthentication and keysRate limits and errorsUploading assetsFoldersUploading templatesTriggering a flowRuns and creativesAPI Request deliveryCallbacks
    All docs
    Motion Scripting
    / Language

    JavaScript support

    Which parts of modern JavaScript scripts can use, and the short list of exclusions that keep evaluation deterministic.

    Scripts are modern JavaScript - the current ECMAScript standard library, minus a small set of exclusions that exist to keep evaluation deterministic and sandboxed. If a construct is ordinary JavaScript and not listed below, it works: classes, arrow functions, destructuring, template literals, iterators, Map/Set, typed arrays, JSON, the full Math object and friends.

    The module shape#

    A script is a module. Its top level runs ONCE when the script compiles - the place for constants, helper functions and module-level handles - and the exported frame() runs once per evaluated frame:

    export const outputs = ["layer_1:transform.position"];
    
    const RADIUS = 120;
    
    export function frame({ time, dt, frame, fps }) {
      return [320 + Math.cos(time) * RADIUS, 180 + Math.sin(time) * RADIUS];
    }
    

    The argument to frame() carries the clock: time (seconds), dt (one frame in seconds), frame (the integer frame) and fps. The same values are available as globals, with ONE caution: inside frame() the bare word frame names the function itself, so destructure { frame } from the argument whenever you need the frame number in the body.

    Excluded on purpose#

    • eval and new Function - no code from strings; both throw immediately.
    • WeakRef and FinalizationRegistry - garbage-collector timing must never influence a frame.
    • SharedArrayBuffer and Atomics - no shared memory, no timing channels.
    • Date.now() and the real clock - Date reports the comp's time; the time zone is pinned to UTC on every host.
    • Unseeded Math.random - the global is replaced by the seeded stream, the same numbers on every machine (see Determinism).
    • Host surfaces - no fetch, no DOM, no workers, no storage. typeof window is "undefined", exactly as in any plain sandbox.

    Absent libraries#

    Intl and Temporal are not present - locale tables and calendar databases would make renders differ between machines. Format numbers with the standard tools instead (toFixed, padStart, template literals - the Formatting page collects the recipes), and do date maths in frames and seconds.

    Promises settle inside the frame#

    async helpers and promises work, but everything must SETTLE within the frame being evaluated - a frame's value cannot arrive later. A frame() whose returned promise never settles reports the typed async_unsettled error. In practice: use plain synchronous code in frame(); there is nothing asynchronous worth awaiting inside a sandbox with no outside world.

    Budgets, not trust#

    The runtime does not rely on scripts being polite. Poll budgets stop runaway loops, a memory ceiling stops runaway allocation and a stack guard stops runaway recursion - each reported as a typed status while the frame renders with base values. The numbers live on the Budgets page.