JavaScript SDK
Build Actors in Node.js: get the SDK, imports, and a minimal Actor.
The JavaScript SDK (scrapely) is the runtime library for JavaScript and TypeScript Actors on Scrape.ly. It combines the Actor lifecycle and platform APIs with Crawlee crawlers, storages, the platform proxy, the opt-in Scrape.ly browser, logging, and pay-per-event charging. It is API-compatible with the Apify SDK, and parts of it are derived from the Apify SDK (Apache-2.0), so most Apify Actors run unchanged.
The source code is on GitHub: scrapely-app/scrapely.
Get the SDK
On the platform
You don't install the SDK for platform runs. Every Node.js Actor builds on a scrapely/actor-node* base image that already contains scrapely and its API client (scrapely-client) under /opt/scrapely.
| Image | Contents |
|---|---|
scrapely/actor-node | Node.js only, for HTTP crawlers and plain scripts |
scrapely/actor-node-playwright | Playwright |
scrapely/actor-node-playwright-chrome | Playwright with Chrome |
scrapely/actor-node-playwright-firefox | Playwright with Firefox |
scrapely/actor-node-playwright-webkit | Playwright with WebKit |
scrapely/actor-node-playwright-camoufox | Playwright with Camoufox |
scrapely/actor-node-puppeteer-chrome | Puppeteer with Chrome |
Each image is tagged by Node.js major version: 20, 22, 24, and 26. Browser images ship browsers that your Actor launches in its container. If you turn on the Scrape.ly browser for the Actor, the build skips browser downloads and launches connect to the hosted browser instead (see Browsers and remote CDP).
If your Actor has no Dockerfile, the build generates one that starts from scrapely/actor-node:20, runs npm ci --omit=dev (or npm install --omit=dev without a lockfile), and starts node main.js in the package root. Add a Dockerfile to choose another image or entrypoint.
With Transform actors enabled (dashboard Settings → Preferences, on by default), the build also:
- links the base image's SDK into your
node_modulesafternpm install, soscrapelyresolves to it even if yourpackage.jsonasks for another version; - adds an
apifyshim when your project doesn't install the realapifypackage; - swaps
apify/actor-node*base images for the matchingscrapely/actor-node*image; - points calls to Apify's LLM gateway (
https://openrouter.apify.actor) at the Scrape.ly LLM gateway.
On your machine
scrapely run starts your entrypoint with your local Node.js, so the SDK has to be in your local node_modules. The SDK is public on npm, and no npm login is needed. In a project created with scrapely init, npm install is enough. Otherwise, install it yourself:
npm install scrapelyVersions 1.2.3 and older of scrapely are an empty placeholder. If an old lockfile pins one of them, run npm install scrapely@latest. To test against the platform itself, push your code and run it with scrapely call; see Errors & deployment.
Locally, the SDK uses Crawlee storage in ./storage, launches browsers on your machine, and has no platform proxy or charging. See Local runs.
Imports
Examples in these docs import from scrapely. On the platform, apify imports resolve to the same module.
import {
Actor,
PlaywrightCrawler,
Dataset,
KeyValueStore,
RequestQueue,
} from 'scrapely';TypeScript types ship with the package. The root package exports:
Actor,ACTOR_PERMISSION_LEVEL,EXIT_CODES, and the Actor option typesConfigurationandPlatformEventManagerApifyClientfromscrapely-clientChargingManager,ChargeUncertainError,ChargeRejectedError, and charging helpersProxyConfigurationandcreateProxyConfigurationfor the platform proxy or your own proxiesBrowserConfiguration,createBrowserConfiguration, andsetCdpUrlfor the Scrape.ly browserScrapelyRequestList,utils, andenqueueLinks- Crawlee crawlers, storages, logging, and the
playwrightUtils/puppeteerUtilsnamespaces
See the API reference for the full list.
Importing the package has side effects:
- It maps
ACTOR_LOG_LEVELandACTOR_LOG_FORMATto Crawlee's log settings. - It patches Crawlee's browser pool, and the Playwright and Puppeteer launchers, so browsers connect to the Scrape.ly browser when the Actor has it turned on. With the setting off (the default), launches are left alone.
Import the SDK before other Crawlee modules so the log settings apply.
How an Actor runs
A platform run is a container with a run context. Scrape.ly injects the run ID, a scoped token, the API URL, default storage IDs, input, timeout, and the events WebSocket URL as environment variables (see Environment). The SDK reads them when you call Actor.init().
Actor.init()connects API-backed storage, the platform events WebSocket, and charging.- The Actor reads input with
Actor.getInput()orActor.getInputOrThrow(). - Crawler code processes requests and writes to datasets, key-value stores, and request queues.
- Platform events (
persistState,migrating,aborting,systemInfo) arrive while the Actor works. Actor.main()orActor.exit()closes events, flushes storage and charges, and ends the process.
Always await writes. The process can end before an un-awaited dataset or key-value store write reaches the API.
Minimal Actor
import { Actor } from 'scrapely';
await Actor.main(async () => {
const { url } = await Actor.getInputOrThrow<{ url: string }>();
const response = await fetch(url);
await Actor.pushData({ url, status: response.status });
});Where to go next
| Topic | Page |
|---|---|
init, main, exit, fail, local runs, signals | Lifecycle |
getInput, pushData, getValue, setValue | Input & output |
| Datasets, key-value stores, queues, Crawlee | Storages & Crawlee |
Proxy, events, useState, status messages | Proxy & events |
call, start, abort, metamorph, webhooks, charging | Actors & webhooks |
getEnv, run metadata, Scrape.ly browser, API client | Environment |
| Standby mode and HTTP-serving Actors | Standby |
| Errors, testing, deployment | Errors & deployment |
| Every exported symbol and signature | API reference |