JavaScript Execution
RTILA X provides two powerful ways to run custom JavaScript code during your automation: execute_script (browser-side) and run_script (server-side). These commands give you unlimited flexibility to implement custom logic that goes beyond the built-in commands.
Understanding the difference between these two execution environments is critical. They run in completely different contexts with different capabilities.

execute_script (Browser-Side)
Section titled “execute_script (Browser-Side)”What It Does
Section titled “What It Does”execute_script runs JavaScript code inside the browser page context. The code executes in the same JavaScript environment as the web page itself, with full access to the DOM, browser APIs, and page state.
Think of it as opening the browser’s Developer Console and typing JavaScript directly. The code can see and manipulate everything on the page.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
script |
string | ✅ Yes | — | The JavaScript code to execute in the browser. The code runs in the page’s JavaScript context. |
output_variable |
string | No | — | The name of the variable to store the script’s return value in. If not set, the result is returned but not stored. |
What’s Available
Section titled “What’s Available”When your script runs via execute_script, it has access to:
| Object | Description |
|---|---|
document |
The DOM document. Access elements, create elements, modify the page. |
window |
The browser window object. Access window properties, navigation, storage. |
localStorage |
The page’s localStorage. Read/write persistent page data. |
sessionStorage |
The page’s sessionStorage. Read/write session data. |
| All browser APIs | Standard browser JavaScript APIs (fetch, XMLHttpRequest, etc.) |
| Page-specific objects | Any JavaScript objects the page defines (e.g., React state, Vue data). |
What’s NOT Available
Section titled “What’s NOT Available”| Not Available | Why |
|---|---|
state.variables |
Runtime variables are server-side. Use ${variable} substitution before the script runs. |
| File system access | Browser scripts can’t access the file system. Use run_script instead. |
| Node.js / Deno APIs | These are server-side. Not available in the browser. |
Examples
Section titled “Examples”Get the page title:
{ "command": "execute_script", "params": { "script": "return document.title;", "output_variable": "page_title" }}Get all links on the page:
{ "command": "execute_script", "params": { "script": "return Array.from(document.querySelectorAll('a')).map(a => ({text: a.textContent.trim(), href: a.href}));", "output_variable": "all_links" }}Click an element using JavaScript:
{ "command": "execute_script", "params": { "script": "document.querySelector('.submit-button').click(); return 'clicked';", "output_variable": "click_result" }}Get computed styles:
{ "command": "execute_script", "params": { "script": "const el = document.querySelector('.price'); return window.getComputedStyle(el).color;", "output_variable": "price_color" }}Read localStorage:
{ "command": "execute_script", "params": { "script": "return JSON.parse(localStorage.getItem('userSession') || '{}');", "output_variable": "session_data" }}Variable Access in execute_script
Section titled “Variable Access in execute_script”You cannot directly access RTILA runtime variables inside execute_script. However, you can use ${variable} substitution in the script string itself, which RTILA resolves before the script runs:
{ "command": "execute_script", "params": { "script": "const searchTerm = '${search_term}'; const results = document.querySelectorAll('[data-name*=\"' + searchTerm + '\"]'); return results.length;", "output_variable": "match_count" }}In this example, ${search_term} is replaced with the actual value before the script is sent to the browser.
run_script (Server-Side Deno)
Section titled “run_script (Server-Side Deno)”What It Does
Section titled “What It Does”run_script runs JavaScript code in RTILA X’s Deno engine (server-side). The code runs outside the browser, with access to the automation state, file system, network, and RTILA’s helper functions.
Think of it as running a script on your computer that can control the browser, access files, and make network requests.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
script |
string | ✅ Yes | — | The JavaScript code to execute in the Deno engine. |
What’s Available
Section titled “What’s Available”When your script runs via run_script, it has access to:
| Object | Description |
|---|---|
state.variables |
All runtime variables. Access with state.variables.name. |
state.memory |
Persistent memory that survives across iterations. |
page |
The Playwright page object. Full browser control. |
context |
The browser context object. |
helpers |
Utility functions provided by RTILA. |
state |
The full automation state object. |
| Deno APIs | File system, network, and other Deno built-in modules. |
What’s NOT Available
Section titled “What’s NOT Available”| Not Available | Why |
|---|---|
document / window |
These are browser objects. Use page.evaluate() to access the DOM from server-side. |
| Browser localStorage | Not accessible from server-side. Use page.evaluate() instead. |
| Direct DOM manipulation | Use page.evaluate() or page.click() etc. instead. |
Examples
Section titled “Examples”Calculate a discounted price:
{ "command": "run_script", "params": { "script": "const price = parseFloat(state.variables.raw_price); const discounted = price * 0.85; state.variables.discounted_price = discounted.toFixed(2);" }}Wait and then click:
{ "command": "run_script", "params": { "script": "await helpers.sleep(2000); await page.click('.load-more-button');" }}Read a file from the file system:
{ "command": "run_script", "params": { "script": "const content = await Deno.readTextFile('output/config.json'); const config = JSON.parse(content); state.variables.config = config;" }}Make a network request:
{ "command": "run_script", "params": { "script": "const response = await fetch('https://api.example.com/data'); const data = await response.json(); state.variables.api_data = data;" }}Use page.evaluate() to access the DOM:
{ "command": "run_script", "params": { "script": "const title = await page.evaluate(() => document.title); state.variables.page_title = title;" }}Variable Access in run_script
Section titled “Variable Access in run_script”In run_script, you access runtime variables through the state.variables object:
// Reading a variableconst myVar = state.variables.my_variable;
// Setting a variablestate.variables.new_variable = "some value";
// Reading from memory (persists across iterations)const cached = state.memory.cached_data;
// Setting memorystate.memory.cached_data = { key: "value" };Script Transformations in Datasets
Section titled “Script Transformations in Datasets”Script transformations are a special use of JavaScript within dataset properties. They transform extracted values during the extraction process.
How They Work
Section titled “How They Work”- A property extracts a raw value from the page.
- The script transformation receives the value as the
valuevariable. - Your JavaScript code transforms the value.
- The transformed value replaces the original in the output.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
type |
string | ✅ Yes | — | Set to "script" |
code |
string | ✅ Yes | — | JavaScript code. Must return the transformed value. |
default_value |
any | No | null | Value to return if the script throws an error. |
Examples
Section titled “Examples”Convert to uppercase:
{ "type": "script", "code": "return value.toUpperCase();", "default_value": ""}Parse a price and apply a discount:
{ "type": "script", "code": "const price = parseFloat(value.replace(/[^0-9.]/g, '')); return (price * 0.85).toFixed(2);", "default_value": "0"}Extract domain from URL:
{ "type": "script", "code": "try { return new URL(value).hostname; } catch(e) { return value; }", "default_value": ""}Split and get first element:
{ "type": "script", "code": "return value.split(',')[0].trim();", "default_value": ""}Remove HTML tags:
{ "type": "script", "code": "return value.replace(/<[^>]*>/g, '').trim();", "default_value": ""}Script Transformation Rules
Section titled “Script Transformation Rules”| Rule | Description |
|---|---|
Must use return |
The script must return the transformed value. Without return, the result is undefined. |
value is the input |
The current extracted value is available as the value variable. |
| Use try/catch | Handle errors to prevent the extraction from failing. |
Set default_value |
Provides a fallback if the script throws an error. |
| Standard JavaScript only | No browser APIs, no Deno APIs. Just standard JavaScript. |
Key Differences: execute_script vs run_script
Section titled “Key Differences: execute_script vs run_script”| Aspect | execute_script | run_script |
|---|---|---|
| Execution environment | Browser page context | Deno engine (server-side) |
| DOM access | ✅ Direct (document, window) |
❌ Use page.evaluate() |
| File system access | ❌ No | ✅ Yes (Deno.readTextFile, etc.) |
| Network access | ✅ Via browser (fetch, XHR) | ✅ Via Deno (fetch, etc.) |
| Runtime variables | ❌ Use ${variable} substitution |
✅ Via state.variables |
| Memory access | ❌ No | ✅ Via state.memory |
| Browser control | ❌ Limited to page JS | ✅ Full Playwright API |
| Use case | Page manipulation, DOM queries | Complex logic, file operations, API calls |
| Performance | Fast (runs in browser) | Slightly slower (server-side) |
| Security context | Page’s security context | RTILA’s security context |
When to Use Which
Section titled “When to Use Which”| Scenario | Use | Why |
|---|---|---|
| Get page title or URL | execute_script |
Direct DOM access is simplest |
| Click an element | execute_script |
Direct DOM manipulation |
| Read page content | execute_script |
Direct DOM access |
| Calculate a value | run_script |
Server-side computation |
| Read a file | run_script |
File system access needed |
| Make an API call | run_script |
Server-side network access |
| Wait and then act | run_script |
helpers.sleep() available |
| Manipulate page elements | execute_script |
Direct DOM access |
| Complex data processing | run_script |
Full JavaScript with state access |
| Transform extracted data | Script transformation | Runs during extraction |
Security Warnings
Section titled “Security Warnings”| Warning | Description |
|---|---|
run_script has full system access |
It can read/write files, make network requests, and control the browser. Only run scripts you trust. |
execute_script runs in page context |
It can access page data, cookies, and localStorage. Be careful with sensitive pages. |
| Don’t run untrusted scripts | Only run JavaScript you’ve written or thoroughly reviewed. |
| Sanitize user input | If your script processes user-provided data, sanitize it to prevent injection attacks. |
| Use try/catch | Always wrap script logic in try/catch to prevent errors from stopping the automation. |
| Avoid infinite loops | Scripts with infinite loops will hang the automation. Add loop limits. |
Performance Tips
Section titled “Performance Tips”| Tip | Why It Matters |
|---|---|
| Prefer built-in commands when possible | Built-in commands are optimized. Use scripts only when necessary. |
| Keep scripts short | Shorter scripts execute faster and are easier to debug. |
| Avoid heavy DOM operations in execute_script | Large DOM manipulations can slow down the page. |
| Use helpers.sleep() in run_script | Add delays between actions to avoid rate limiting. |
| Cache results in state.memory | Avoid recalculating values on every iteration. |
| Use page.evaluate() sparingly | Each page.evaluate() call has overhead. Batch operations when possible. |