Library / SDK
alpacahq/alpaca-trade-api-js avatar
alpacahq/alpaca-trade-api-js

alpaca-trade-api-js: one TypeScript SDK for trading and market data

Node.js library for Alpaca Trade API.

602 stars154 forksTypeScriptApache-2.0

At a glance

What is it?
Version 5 of the Alpaca Node SDK puts the Trading API and Market Data API under one client with typed errors, retries, pagination and streaming, and it quietly changes which features work depending on the runtime you deploy to.
Who is it for?
Adopt alpaca-trade-api-js if you are building a Node or Bun service that trades or streams market data and want one typed client instead of hand-written REST calls. Do not call it from a browser, since the key secret would ship to the client, and check your runtime against the export conditions before you rely on stockStream or submitAndWait.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two APIs, two namespaces, one Alpaca facade

The package is a Node.js TypeScript SDK for the Alpaca Trading API and the Market Data API, and the structural decision is that both live under their own namespace inside a single package, trading and marketData, fronted by one unified Alpaca client. The client constructor takes a keyId, a secret and a paper flag, and paper trading is the default, so a fresh script that forgets the flag is not going to place live orders by accident. That flag is spelled out in the quick start as set false for live trading, which is a reasonable safety posture for a financial SDK. Around the facade the README lists typed errors, resilience covering retry, timeout and rate limiting, pagination helpers, ergonomic order builders and real-time streaming. The package is published to npm as @alpacahq/alpaca-trade-api at version 5.0.0 in the repository metadata, and the licence is Apache-2.0.

Export conditions pick the REST build when WebSockets cannot run

The most consequential design choice in the package is invisible until you deploy somewhere unusual. The runtime compatibility table marks WebSocket streaming as supported only on Node.js 20 and newer and on Bun, where the ws module runs. Deno, Cloudflare Workers or workerd, Vercel Edge and browsers are all marked as unsupported for WebSockets. On those targets the export conditions resolve the root import to a WebSocket-free REST build: workerd, worker, edge-light, deno and browser each point at the REST entrypoint, while the plain import condition points at the full build. The consequence for a developer is a runtime error rather than a build error, since the stream factories such as stockStream and stream, plus submitAndWait, throw when called on a REST-only target. If your deployment target might be an edge function, check the table before you design around streaming, because the failure appears at call time on a platform where you cannot run WebSockets anyway.

The browser build works, and that is exactly the problem

The README is explicit about browsers. Calling Alpaca directly from a browser ships your APCA_API_SECRET_KEY to the client, so the package resolves to the REST build and works technically, but it is discouraged. The recommendation is to prefer a server or proxy, and the repository ships examples/marketdata-backend.ts as the pattern, a backend that holds the credentials and serves market data onward. The .env.example file in the repository makes the same point in a comment: copy it to .env, fill in the credentials, and never commit real credentials because .env is git-ignored. The file also shows the authentication options, API key authentication with APCA_API_KEY_ID and APCA_API_SECRET_KEY, and OAuth through APCA_API_OAUTH_TOKEN, with a note that when both environment schemes are populated OAuth takes precedence, while explicit key options still select key authentication. Two further variables, PORT and SYMBOLS, exist only for the market data backend example, with defaults of 8080 and AAPL,MSFT.

A first session against paper trading in a dozen lines

Installing the package is the usual npm step:

bash
npm install @alpacahq/alpaca-trade-api

The quick start then creates the client, reads the account, pulls a latest price and opens a bar stream:

ts
import { Alpaca } from "@alpacahq/alpaca-trade-api";

const alpaca = new Alpaca({
  keyId: process.env.APCA_API_KEY_ID,
  secret: process.env.APCA_API_SECRET_KEY,
  paper: true, // default; set false for live trading
});

const account = await alpaca.trading.account.getAccount();
const price = await alpaca.marketData.getLatestPrice("AAPL");

const bars = alpaca.marketData.stockStream({ feed: "iex" });
bars.onBar((b) => console.log(b.symbol, b.close));
bars.onConnect(() => bars.subscribeForBars(["AAPL", "MSFT"]));
bars.connect();

Two details in that snippet carry most of the weight. The credentials are read from environment variables rather than hardcoded, which is what the .env.example file sets up for you. And the subscription happens in the onConnect callback rather than before connect, so the subscription request is sent only once the socket is open. The order of those two calls is the difference between a stream that receives data and one that silently receives nothing.

Activity streams over SSE with cancellation and resumption

Not everything has to go through a WebSocket. The facade provides typed async Server-Sent Events subscriptions with cancellation, reconnection and Last-Event-ID resumption, which covers account activity feeds on platforms where a socket is not available:

ts
const controller = new AbortController();
const activities = await alpaca.trading.subscribeActivities(
  {},
  { signal: controller.signal },
);

try {
  for await (const activity of activities) {
    console.log(activity.activityType, activity.details);
  }
} finally {
  activities.close();
}

The shape is an async iterable, which means a for await loop over the stream, and the subscription takes a second argument carrying an AbortSignal, so cancelling is done with an AbortController rather than by leaving a socket dangling. The close call in the finally block matters for the same reason: on the REST-only runtimes this is the streaming mechanism you have, so leaving it open can hold a request alive. Corporate action mutations are reachable from the marketData namespace as well, which the README mentions alongside the streaming section.

A codemod and a migration guide for the 3.x jump

Upgrading is treated as a first class concern, which tells you something about how much the API surface has moved. The README points anyone coming from 3.x to a migration guide, available as MIGRATION.md in the repository and on the docs site, which maps common 3.x calls and workflows to their 4.x equivalents. It also ships a codemod at codemods/alpaca-v3-to-v4.js that automates most of the work, so the upgrade is a scripted migration rather than a manual rewrite of every call site. The repository carries several migration documents, MIGRATION.md, MIGRATIONS.md and MIGRATION_V5.md, alongside a CHANGELOG.md and a migrated_examples directory, so the history of the API changes is traceable inside the repository. That is worth noting for a client that moved from 4.x to 5.0.0: the version number moved quickly, and the release tags show v4.0.3 on 2026-09-23, v4.0.4 on 2026-09-25 and v5.0.0 on 2026-10-01, so if you are on an older major you should budget for the migration rather than a patch bump.

Node 20 for consumers, Node 24 for the repository

There are two Node floors and they are not the same. Consumers of the SDK need Node.js 20 or newer, because the REST transport relies on the platform-global fetch, Headers, URL and AbortController, and the package declares engines.node >=20 in the package metadata. Node 18 reached end of life in April 2025 according to the README, which is why the floor was raised. Contributors need Node.js 24, set in the.nvmrc file, and the build, documentation, generation and release tooling run on Node 24, while CI separately exercises the packed SDK on Node 20 to protect the consumer floor. The dependency on platform globals has a further consequence for TypeScript users: strict Node TypeScript projects can leave the DOM libraries out, and the REST declarations are portable and do not require dom in the consumer tsconfig. The repository also ships a CHANGELOG, a CONTRIBUTING guide, a biome configuration, a vitest configuration and a tsup build configuration, and the last push was on 2026-10-22 with the repository not archived.

Editorial conclusion

Adopt alpaca-trade-api-js if you are building a Node or Bun service that trades or streams market data and want one typed client instead of hand-written REST calls. Do not call it from a browser, since the key secret would ship to the client, and check your runtime against the export conditions before you rely on stockStream or submitAndWait.

Frequently asked questions

How do I install and start using the Alpaca Node SDK?

Run npm install @alpacahq/alpaca-trade-api, create an Alpaca client with a keyId, secret and the paper flag, then call the trading or marketData namespaces. The quick start reads the account, fetches the latest price and opens a stock stream with the iex feed.

Can I use WebSocket streaming on Cloudflare Workers or Vercel Edge?

No. WebSocket streaming is supported on Node.js and Bun only, and on Deno, workerd, edge-light and browser targets the package resolves to the REST build, where stockStream, stream and submitAndWait throw if called.

Is it safe to call the Alpaca API from a browser?

The README says it technically works but is discouraged, because calling Alpaca directly from a browser ships your APCA_API_SECRET_KEY to the client. Use a server or proxy, following the pattern in examples/marketdata-backend.ts.

How do I upgrade from version 3 of the Alpaca SDK?

The migration guide maps common 3.x calls to their 4.x equivalents, and a codemod at codemods/alpaca-v3-to-v4.js automates most of the work. The repository also keeps MIGRATION_V5.md and a migrated_examples directory for newer jumps.

What Node.js version does the Alpaca SDK require?

Consumers need Node.js 20 or newer, since the REST transport uses the platform-global fetch, Headers, URL and AbortController. Contributors need Node.js 24, and CI separately runs the packed SDK on Node 20 to keep the consumer floor honest.

Official sources

  1. alpacahq/alpaca-trade-api-js on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/alpacahq-alpaca-trade-api-js.svg)](https://hysenlabs.com/projects/alpacahq-alpaca-trade-api-js)

Was this useful?