• Introduction
  • Requirements
  • ReaScript Documentation
  • Running ReaScripts
  • Editing and Debugging
  • Getting started
  • Advanced

    top  Introduction

    ReaScript is a feature that allows you to edit, run and debug scripts within REAPER. Scripts are simple text files from which you can call any REAPER action, and also call back into most of the REAPER API functions (the same API used by compiled REAPER plug-ins and extensions). ReaScript can be used to create anything from advanced macros to full-featured REAPER extensions.

    Supported scripting languages:
    A language developed in-house (but open source) which has some similarities to C and JavaScript. EEL is also used to write JSFX plug-ins, OSCII-bot scripts, and video processing effects in REAPER. EEL offers outstanding run-time performance. It supports basic UI management (dedicated script window, docking, context menus, mouse input, etc) and graphics manipulation (drawing primitives, loading image files, etc). EEL is embedded within REAPER and requires no additional downloads or settings.
    Lua (v5.3)
    A popular scripting language. Lua is probably easier to learn and use than EEL or Python, and offers good performance. It supports the same UI and graphic features as EEL. As a general-use scripting language, Lua also benefits from third-party resources, libraries, tutorials, and code examples. Lua is embedded within REAPER and requires no additional downloads or settings.
    Python (v2.7-v3.x)
    Another popular scripting language. Python must be downloaded and installed separately (see requirements) and as such, will never be as portable between users as EEL or Lua. Within REAPER, Python performance is not as good as EEL or Lua, and does not offer any UI or graphic features. However, Python does benefit from a vast number of third-party resources, libraries, tutorials, and code examples.

    top  Requirements

    EEL and Lua are embedded within REAPER and will work automatically.

    Python requirements
    You must have Python installed on your computer and enabled in REAPER preferences (Options > Preferences > Plug-Ins > ReaScript). ReaScript should work with any version of Python between 2.7 and the current 3.x release. OS X normally comes with Python already installed. If you don't already have Python, it is available as a free download for Windows or Mac from multiple sources. For 32-bit REAPER, you need 32-bit Python (regardless of the operating system). For 64-bit REAPER, you need 64-bit Python. A list of Python distributions is here.

    Once Python is installed, REAPER should automatically detect it, and ReaScript will work. If REAPER does not detect Python, you can enter the Python install directory manually in REAPER preferences.

    top  ReaScript Documentation

    ReaScript documentation is available online , but the API is extended frequently, and up-to-date documentation can be generated by REAPER itself.

    From within REAPER, under the Help menu, choose "ReaScript documentation". This will open a web page with a complete list of REAPER Extension API functions that can be called from ReaScript. This help page will also explain the basics of how to call API functions and how to import functions/modules from other ReaScripts, and list additional REAPER-specific built-in functions that are available for each scripting language.

    EEL documentation
    Since JSFX are written in EEL, you can refer to the JSFX documentation; specifically, these sections: File I/O and network functions differ from JSFX, and are described in the REAPER-generated ReaScript documentation, within the list of EEL built-in functions (see fopen(), tcp_connect(), et al)
    Lua documentation
    The Lua v5.3 reference manual is available here.

    REAPER-specific functions (mostly UI/graphic functions) are also described in the REAPER-generated ReaScript documentation, within the list of Lua built-in functions.
    Python documentation
    There is extensive online documentation for Python 2 and Python 3.

    top  Running ReaScripts

    You will need to either write a new script, or load a script from another user. Scripts can be placed anywhere on disk, but it is convenient to keep them all in the REAPER/Scripts resource directory. To find the resource directory: Options > Show resource path in explorer/finder.

    To create a new script, show the Actions window (bound to the ? key by default), and click ReaScript: "New...". You will be prompted for the location to save the script (the default location is the recommended REAPER/Scripts resource directory). The type of script will be deduced from the file extension you enter (.eel, .lua, or .py).

    To load a script, click ReaScript: "Load..." in the Actions window, and select the script file you want to add to the action list (multiple selection is allowed).

    Once you have written or loaded a script, it will be added to the action list, and you can treat the script just like any custom action: run it from the Actions window ("Run" button, or double-click), bind it to a key shortcut, mouse wheel, MIDI/OSC controller, or toolbar button. You can get binding information at runtime too, details here.

    ReaScripts can also be run à la carte, via the actions "ReaScript: run..." and "ReaScript: run last script".

    top  Editing and Debugging

    To edit and/or debug a script, select it the Actions window, and click ReaScript: "Edit...".
    The ReaScript Integrated Developement Environment (ReaScript IDE) will open:

    REAPER ReaScript IDE

    The right pane shows both built-in and user defined variables, which is handy for debugging.

    top  Getting started

    Just try it. Experiment!

    ReaScript is mostly fault-tolerant. Most programming mistakes will give error messages that will help you fix the mistake. While it is still possible to crash REAPER with scripts, you shouldn't be able to do any permanent damage -- just be sure to save any important projects before testing ReaScripts.

    A very simple way to test ReaScript is by calling the API test function:
    When you run this script, you should see a window that says "Test OK".

    Common reasons for scripts failing are:
    • Syntax error: typo, missing newline, incorrect indentation in Python, etc.
    • Unknown extension API. Perhaps the script was written against a newer version of REAPER.
    • Incorrect use of the Extension API. Verify how the function parameters and return value should be used in the REAPER-generated ReaScript documentation.
    • Lua: invalid "objects". Check variables for nil before passing to functions.
    • Python: REAPER cannot find the Python library. Is the proper 32/64-bit Python installed? Is it enabled in Preferences?
    REAPER should show an error message when a script fails, which will point to the faulty line, when possible.

    To call any REAPER built-in action from ReaScript, use Main_OnCommand(actionID, 0). Find the ID of a given action by opening the Actions window, and right-clicking it: "Copy selected action ID". For example, from ReaScript/EEL you would call the REAPER action "Item: Split item under mouse cursor" like this:
    Main_OnCommand(40746, 0);

    top  Advanced

    Deferred scripts
    By default, ReaScripts are run on-demand and terminate after execution. However, you can write scripts that run in the background until terminated by the user. This can be used to write scripts that react to events, such as the current playback position, a track selection change, user input, etc. See defer()/ reaper.defer()/ RPR_defer() and atexit()/ reaper.atexit()/ RPR_atexit() in the REAPER-generated ReaScript documentation.

    A deferred script with a user interface window will run modelessly, and can be docked, just like a built-in REAPER window.

    The list of scripts that are currently running in the background is available in the Actions menu. To stop a deferred script, or to run a new instance, click the script in this list. Note that no undo point is automatically added when running/terminating deferred scripts, unless you create one explicitly.

    ReaScripts can keep persistent data by using standard file functions, but the following API functions are recommended for portability:
    • SetExtState() and GetExtState() allow ReaScripts to set and get key/value pairs that will persist between ReaScripts, and optionally persist between REAPER instances as well. For example, a Python module called "utility" might want to remember that some flag is set:
      RPR_SetExtState("utility", "someflag", "2", True)
      val=RPR_GetExtState("utility", "someflag") # even if called after REAPER is closed and reopened, val will be equal to "2"
    • SetProjExtState() and GetProjExtState() allow ReaScripts to save data within the project RPP file.

    Undo points are created for ReaScripts by default. To prevent the automatic addition of an undo point, a script can call defer()/ reaper.defer()/ RPR_defer().

    There are also API functions for manually creating undo points, as well as API functions to Undo and Redo previous points.

    The best way to manually create an undo point for your script is to call Undo_BeginBlock() before most of your code, and Undo_EndBlock() after your code finishes.

    • These functions operate on the active project only (if multiple tabs are open) -- do not switch project tabs from your code while in an Undo block.
    • You must always pair Undo_BeginBlock with Undo_EndBlock. If you call Undo_BeginBlock and then fail to call Undo_EndBlock, an undo block will be left open, which may cause undesired undo behaviors.
    • The final parameter of Undo_EndBlock is a bitmask of what you would like to add to the undo state. If you are simply calling other actions (via Main_OnCommand or similar functions), this should be 0. If you modify the state of the project directly, it's safest to set the bitmask to -1. A more specific combination of flags may be an optimization, depending on what your script is doing.
    • Always give the "desc" parameter of Undo_EndBlock a valid (non-empty) descriptive string.
    Lua example:
    m = reaper.GetMasterTrack(0)
    reaper.TrackFX_GetByName(m, "ReaEQ", 1)
    reaper.Undo_EndBlock("Add ReaEQ FX to the master track", -1)
    undo flags for Undo_EndBlock() et al:
    • 1: track configurations
    • 2: track FX
    • 4: track items
    • 8: project states
    • 16: freeze states

    Action binding
    You can query various contextual information about the script, at runtime, using get_action_context()/ reaper.get_action_context() (sorry, no Python support) . You can retrieve MIDI/OSC/mouse-wheel/trackpad input values when the script is bound to MIDI/OSC controllers (both absolute and relative modes are supported), or to the mouse-wheel/trackpad.

    Here is a basic Lua example which monitors received MIDI/OSC input values:
    function run()
      is_new,name,sec,cmd,rel,res,val = reaper.get_action_context()
      if is_new then
        reaper.ShowConsoleMsg(name .. "\nrel: " .. rel .. "\nres: " .. res .. "\nval = " .. val .. "\n")
    function onexit()

    Toggle state
    ReaScripts can have ON/OFF states. Here is a minimal EEL example that toggles the current state each time the script is performed. If this script were bound to a toolbar button, each button press would alternately turn the button on or off.
    get_action_context(#fn, sec, cmd);
    state = GetToggleCommandStateEx(sec, cmd);
    SetToggleCommandState(sec, cmd, state<=0?1:0);
    RefreshToolbar2(sec, cmd);

    For more help on ReaScript, to download script examples, to report bugs, to request additional API functions, to share ReaScripts, or just to discuss the possibilities, please use the REAPER ReaScript Forum.

  •   Home
        Old Versions
        Language Packs
        Theme Development
        Custom Cursors
        JSFX Programming
      • ReaScript
        Extensions SDK
        Extensions to VST SDK
        Language Pack Template
        User Guide