TypeScript/Node.js SDK
The Grasp TypeScript/Node.js SDK provides a comprehensive solution for browser automation, code execution, file management, and terminal operations in cloud environments.
Installation
pnpm add @grasplabs/grasp
npm install @grasplabs/grasp
yarn add @grasplabs/grasp
Basic Usage
import { Grasp } from '@grasplabs/grasp';
import { chromium } from 'playwright';
async function main() {
// Create Grasp instance with API key
const grasp = new Grasp({
apiKey: process.env.GRASP_KEY || 'your_api_key_here'
});
// Launch a new session
const session = await grasp.launch({
browser: {
type: 'chrome-stable',
headless: false,
adblock: true
},
keepAliveMS: 300000, // Keep session alive for 5 minutes
timeout: 3600000, // Max session duration: 1 hour
debug: true
});
console.log('Session ID:', session.id);
// Connect to the browser using Playwright
const browser = await chromium.connectOverCDP(session.browser.getEndpoint(), {
timeout: 150000,
});
// Create page and navigate
const page = await browser.newPage();
await page.goto('https://getgrasp.ai/', { waitUntil: 'domcontentloaded' });
await page.screenshot({ path: 'grasp-ai.png' });
// Use session services
await session.files.uploadFile('./local-file.txt', '/home/user/remote-file.txt');
const fileContent = await session.files.readFile('/home/user/remote-file.txt');
console.log('File content:', fileContent);
// Run terminal commands
const command = await session.terminal.runCommand('ls -la /home/user');
command.stdout.pipe(process.stdout);
await command.end();
// Clean up resources
await page.close();
await browser.close();
await session.close();
console.log('✅ Task finished.');
}
main();
API Reference
new Grasp(options)
Creates a new Grasp instance for managing browser sessions.
Parameters:
options
(object, optional):apiKey
(string): Grasp API key (defaults toGRASP_KEY
environment variable)
Example:
const grasp = new Grasp({
apiKey: 'your_api_key_here'
});
grasp.launch(options)
Launches a new browser session with comprehensive services.
Parameters:
options
(object, optional):browser
(object, optional): Browser configurationtype
(string, optional): Browser type -'chromium'
or'chrome-stable'
. Default:'chromium'
headless
(boolean, optional): Run in headless mode. Default:true
adblock
(boolean, optional): Enable ad blocking. Default:false
liveview
(boolean, optional): Enable live view for real-time browser monitoring. Default:false
keepAliveMS
(number, optional): Keep session alive duration in millisecondstimeout
(number, optional): Max session duration in milliseconds. Default: 900000 (15 minutes), Max: 86400000 (24 hours)debug
(boolean, optional): Enable debug mode. Default:false
logLevel
(string, optional): Log level -'debug'
,'info'
,'warn'
,'error'
. Default:'info'
Returns:
Promise<GraspSession>
: Session object with browser, terminal, files, and codeRunner services
Example:
const session = await grasp.launch({
browser: {
type: 'chrome-stable',
headless: false,
adblock: true,
liveview: true
},
keepAliveMS: 300000,
timeout: 3600000,
debug: true,
logLevel: 'debug'
});
grasp.connect(sessionId)
Connects to an existing browser session.
Parameters:
sessionId
(string): The ID of the existing session to connect to
Returns:
Promise<GraspSession>
: Session object for the existing session
Example:
const session = await grasp.connect('existing-session-id');
GraspSession
The main session object that provides access to all Grasp services.
Properties:
id
(string): Unique session identifierbrowser
(GraspBrowser): Browser service for CDP connections and browser managementterminal
(TerminalService): Terminal service for running shell commandsfiles
(FileSystemService): File system service for file operationscodeRunner
(CodeRunner): Code execution service for running Python/JavaScript code
Methods:
session.getHost(port)
Gets the host URL for a specific port in the session.
Parameters:
port
(number): Port number
Returns:
string
: Host URL for the specified port
session.close()
Closes the session and releases all resources.
Returns:
Promise<void>
Example:
const session = await grasp.launch();
console.log('Session ID:', session.id);
// Use session services
const browser = session.browser;
const terminal = session.terminal;
const files = session.files;
const codeRunner = session.codeRunner;
// Get host for port 3000
const host = session.getHost(3000);
// Close session when done
await session.close();
Using with Playwright
After launching a session, connect to the browser using Playwright's CDP connection:
import { chromium } from 'playwright';
const session = await grasp.launch();
const browser = await chromium.connectOverCDP(session.browser.getEndpoint(), {
timeout: 150000
});
// Use browser as normal Playwright browser instance
const page = await browser.newPage();
// ... your automation code
await browser.close();
await session.close();
GraspBrowser
Browser service for managing CDP connections and browser-related operations.
Methods:
browser.getHost()
Gets the browser host URL.
Returns:
string
: Browser host URL
browser.getEndpoint()
Gets the WebSocket endpoint URL for CDP connection.
Returns:
string
: WebSocket URL for connecting with Playwright/Puppeteer
browser.getCurrentPageTargetInfo()
(Experimental)
Gets information about the current page target.
Returns:
Promise<object | null>
: Page target information including targetId, sessionId, pageLoaded status, and screenshot
browser.getLiveviewStreamingUrl()
(Experimental)
Gets the live view streaming URL for real-time browser viewing.
Returns:
Promise<string | null>
: Streaming URL or null if not available
browser.getLiveviewPageUrl()
(Experimental)
Gets the live view page URL for browser preview.
Returns:
Promise<string | null>
: Preview page URL or null if not available
browser.downloadReplayVideo(localPath)
(Experimental)
Downloads a replay video of the browser session.
Parameters:
localPath
(string): Local path to save the video file
Returns:
Promise<void>
Example:
const session = await grasp.launch();
const browser = session.browser;
// Get browser endpoint for Playwright connection
const endpoint = browser.getEndpoint();
const playwright = await chromium.connectOverCDP(endpoint);
// Get live view URLs (experimental)
const streamUrl = await browser.getLiveviewStreamingUrl();
const previewUrl = await browser.getLiveviewPageUrl();
// Download replay video (experimental)
await browser.downloadReplayVideo('./replay.mp4');
TerminalService
Terminal service for executing shell commands in the remote environment.
Methods:
terminal.runCommand(command, options)
Executes a shell command and returns a streamable response.
Parameters:
command
(string): Shell command to executeoptions
(object, optional): Command execution optionscwd
(string, optional): Working directory for the commandenvs
(object, optional): Environment variablestimeoutMs
(number, optional): Command timeout in millisecondsuser
(string, optional): User to run the command asbackground
(boolean, optional): Run command in background
Returns:
Promise<StreamableCommandResponse>
: Object with:stdout
(Readable): Standard output streamstderr
(Readable): Standard error streamend()
(function): Wait for command completionkill()
(function): Kill the running commandjson()
(function): Get command result as JSON
Example:
const session = await grasp.launch();
const terminal = session.terminal;
// Run a simple command
const command = await terminal.runCommand('ls -la /home/user');
// Pipe output to console
command.stdout.pipe(process.stdout);
command.stderr.pipe(process.stderr);
// Wait for completion
await command.end();
// Run command with options
const command2 = await terminal.runCommand('npm install', {
cwd: '/home/user/project',
envs: { NODE_ENV: 'development' },
timeoutMs: 300000
});
// Get result as JSON
const result = await command2.json();
console.log('Exit code:', result.exitCode);
console.log('Output:', result.stdout);
FileSystemService
File system service for managing files between local and remote environments.
Methods:
files.uploadFile(localPath, remotePath)
Uploads a file from local system to remote environment.
Parameters:
localPath
(string): Local file pathremotePath
(string): Remote file path
Returns:
Promise<void>
files.downloadFile(remotePath, localPath)
Downloads a file from remote environment to local system.
Parameters:
remotePath
(string): Remote file pathlocalPath
(string): Local file path
Returns:
Promise<void>
files.writeFile(remotePath, content)
Writes content to a file in the remote environment.
Parameters:
remotePath
(string): Remote file pathcontent
(string | ArrayBuffer): File content
Returns:
Promise<void>
files.readFile(remotePath, options)
Reads a file from the remote environment.
Parameters:
remotePath
(string): Remote file pathoptions
(object, optional): Read optionsencoding
(string, optional): File encoding -'utf8'
,'base64'
, or'binary'
. Default:'utf8'
Returns:
Promise<string | ArrayBuffer>
: File content
files.syncDownloadsDirectory(localPath, remotePath)
(Experimental)
Synchronizes the remote downloads directory to local path.
Parameters:
localPath
(string): Local directory pathremotePath
(string, optional): Remote directory path (defaults to localPath)
Returns:
Promise<string>
: Local directory path
Example:
const session = await grasp.launch();
const files = session.files;
// Upload a file
await files.uploadFile('./local-config.json', '/home/user/config.json');
// Write content to remote file
await files.writeFile('/home/user/script.py', 'print("Hello World")');
// Read file content
const content = await files.readFile('/home/user/config.json');
console.log('Config:', JSON.parse(content));
// Read binary file
const binaryData = await files.readFile('/home/user/image.png', {
encoding: 'binary'
});
// Download a file
await files.downloadFile('/home/user/output.txt', './downloaded-output.txt');
// Sync downloads directory (experimental)
const localDir = await files.syncDownloadsDirectory('./downloads');
console.log('Downloads synced to:', localDir);
CodeRunner
Code execution service for running Python and JavaScript code in the remote environment.
Methods:
codeRunner.run(code, options)
Executes Python or JavaScript code and returns the result.
Parameters:
code
(string): Code to execute (Python or JavaScript/TypeScript)options
(object, optional): Execution optionsinject
(boolean, optional): Automatically inject browser connection. Default:false
syncDir
(string, optional): Local directory to sync outputs. Default:'./code-runner'
timeout
(number, optional): Execution timeout in milliseconds. Default:300000
(5 minutes)
Returns:
Promise<CommandResult & { outputDir?: string }>
: Execution result with:exitCode
(number): Exit code of the executionstdout
(string): Standard outputstderr
(string): Standard erroroutputDir
(string, optional): Local directory containing execution outputs
Example:
const session = await grasp.launch();
const codeRunner = session.codeRunner;
// Run Python code
const pythonCode = `
import requests
response = requests.get('https://api.github.com/users/octocat')
print(f"Status: {response.status_code}")
print(f"User: {response.json()['name']}")
`;
const pythonResult = await codeRunner.run(pythonCode, {
timeout: 60000
});
console.log('Python output:', pythonResult.stdout);
// Run JavaScript code
const jsCode = `
const fs = require('fs');
const data = { message: 'Hello from Node.js!' };
fs.writeFileSync('/home/user/downloads/output.json', JSON.stringify(data, null, 2));
console.log('File written successfully');
`;
const jsResult = await codeRunner.run(jsCode, {
syncDir: './my-outputs'
});
console.log('JavaScript output:', jsResult.stdout);
console.log('Output directory:', jsResult.outputDir);
// Run Playwright code with automatic injection
const playwrightCode = `
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch() # This will be auto-injected with CDP connection
page = browser.new_page()
page.goto('https://example.com')
page.screenshot(path='/home/user/downloads/example.png')
browser.close()
`;
const playwrightResult = await codeRunner.run(playwrightCode, {
inject: true, // Automatically inject browser connection
timeout: 120000
});
console.log('Playwright execution completed');
Advanced Examples
Multiple Pages and Contexts
import { Grasp } from '@grasplabs/grasp';
import { chromium } from 'playwright';
async function multiplePages() {
const grasp = new Grasp();
const session = await grasp.launch({
browser: { type: 'chrome-stable' },
timeout: 3600000,
});
const browser = await chromium.connectOverCDP(session.browser.getEndpoint(), {
timeout: 150000,
});
// Create multiple contexts for isolation
const context1 = await browser.newContext();
const context2 = await browser.newContext();
// Pages in different contexts
const page1 = await context1.newPage();
const page2 = await context2.newPage();
// Navigate to different sites
await Promise.all([
page1.goto('https://example.com'),
page2.goto('https://httpbin.org/json')
]);
// Take screenshots and save to downloads
await Promise.all([
page1.screenshot({ path: '/home/user/downloads/example.png' }),
page2.screenshot({ path: '/home/user/downloads/httpbin.png' })
]);
// Download screenshots to local
await session.files.downloadFile('/home/user/downloads/example.png', './example.png');
await session.files.downloadFile('/home/user/downloads/httpbin.png', './httpbin.png');
// Clean up
await context1.close();
await context2.close();
await browser.close();
await session.close();
}
Error Handling
import { Grasp } from '@grasplabs/grasp';
import { chromium } from 'playwright';
async function robustAutomation() {
const grasp = new Grasp();
let session;
let browser;
try {
session = await grasp.launch({
browser: { type: 'chrome-stable' },
timeout: 300000,
});
browser = await chromium.connectOverCDP(session.browser.getEndpoint(), {
timeout: 150000,
});
const page = await browser.newPage();
// Set timeouts
page.setDefaultTimeout(30000);
page.setDefaultNavigationTimeout(60000);
await page.goto('https://example.com');
// Wait for element with error handling
try {
await page.waitForSelector('#some-element', { timeout: 10000 });
await page.click('#some-element');
} catch (error) {
console.log('Element not found, continuing with alternative flow');
// Alternative action
await page.click('body');
}
// Take screenshot for debugging and download
await page.screenshot({ path: '/home/user/downloads/debug.png' });
await session.files.downloadFile('/home/user/downloads/debug.png', './debug.png');
} catch (error) {
console.error('Automation failed:', error);
// Take error screenshot if browser is available
if (browser && session) {
try {
const page = await browser.newPage();
await page.screenshot({ path: '/home/user/downloads/error.png' });
await session.files.downloadFile('/home/user/downloads/error.png', './error.png');
} catch (screenshotError) {
console.error('Failed to take error screenshot:', screenshotError);
}
}
throw error;
} finally {
// Cleanup
if (browser) {
await browser.close();
}
if (session) {
await session.close();
}
}
}
Resource Management
Proper resource management is crucial when working with browser automation:
import { Grasp } from '@grasplabs/grasp';
import { chromium } from 'playwright';
class BrowserManager {
private grasp: Grasp;
private session: any;
private browser: any;
constructor() {
this.grasp = new Grasp();
}
async initialize() {
this.session = await this.grasp.launch({
browser: { type: 'chrome-stable' },
timeout: 3600000,
});
this.browser = await chromium.connectOverCDP(this.session.browser.getEndpoint(), {
timeout: 150000,
});
}
async cleanup() {
if (this.browser) {
await this.browser.close();
this.browser = null;
}
if (this.session) {
await this.session.close();
this.session = null;
}
}
async withPage<T>(callback: (page: any) => Promise<T>): Promise<T> {
const page = await this.browser.newPage();
try {
return await callback(page);
} finally {
await page.close();
}
}
// Access to session services
get files() {
return this.session?.files;
}
get terminal() {
return this.session?.terminal;
}
get codeRunner() {
return this.session?.codeRunner;
}
}
// Usage
const manager = new BrowserManager();
try {
await manager.initialize();
const result = await manager.withPage(async (page) => {
await page.goto('https://example.com');
await page.screenshot({ path: '/home/user/downloads/example.png' });
return await page.title();
});
console.log('Page title:', result);
// Download the screenshot
await manager.files.downloadFile('/home/user/downloads/example.png', './example.png');
} finally {
await manager.cleanup();
}
Important: Resources are automatically released after calling browser.close()
and session.close()
when using the Node.js SDK. Always ensure you properly close browsers, pages, and sessions to avoid resource leaks.
Best Practices
- Always Close Resources: Use
browser.close()
,session.close()
,context.close()
, andpage.close()
appropriately - Error Handling: Implement proper try-catch blocks and cleanup in finally blocks
- Timeout Configuration: Set reasonable timeouts based on your use case
- Context Isolation: Use separate contexts for different tasks to avoid interference
- Concurrent Operations: Use
Promise.all()
for parallel operations when possible - File Management: Use the files service to transfer files between local and remote environments
- Service Integration: Leverage terminal, files, and codeRunner services for comprehensive automation workflows