npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bedrock-rbx/ocale

v0.3.0

Published

Roblox Open Cloud API client

Readme

@bedrock-rbx/ocale

Zero-dependency TypeScript SDK for Roblox Open Cloud.

npm version License: MIT CI

Status: 0.1, pre-1.0. The public API is stabilizing; breaking changes may land in minor releases until 1.0.

What is @bedrock-rbx/ocale?

A typed HTTP client for Roblox Open Cloud. Each Roblox feature (universes, places, game passes, developer products, badges, storage, Luau execution) is exposed as its own client class with the methods, request types, and response types you would otherwise build by hand against the raw REST endpoints.

The SDK has zero runtime dependencies and runs on Node >= 24.12 or Bun >= 1.3 using the standard fetch, FormData, and TextEncoder web APIs. Rate-limit queueing and retry handling are built in: requests are queued per-operation against Roblox's published limits, and idempotent calls automatically retry on 429 and 5xx responses without consumer code reaching for try/catch or setTimeout.

@bedrock-rbx/ocale is the foundation that @bedrock-rbx/core uses internally to talk to Roblox, and it is publishable as a standalone package for anyone building tooling, scripts, or services that need typed Open Cloud calls without bedrock's full IaC engine. If you already depend on @bedrock-rbx/core, ocale is installed transitively; reach for it directly when you need HTTP-level control that core's IaC engine does not expose.

Install

pnpm add @bedrock-rbx/ocale
# or: npm install @bedrock-rbx/ocale
# or: bun add @bedrock-rbx/ocale

Runtime: Node >= 24.12 or Bun >= 1.3.

Authentication: every client takes an apiKey at construction. Generate one at Creator Hub > Credentials > API Keys and grant it the scopes for the operations you plan to call (each method's JSDoc lists its required scopes).

Quick start

import { GamePassesClient } from "@bedrock-rbx/ocale/game-passes";

const client = new GamePassesClient({ apiKey: "your-open-cloud-api-key" });

const result = await client.get({
	gamePassId: "9876543210",
	universeId: "1234567890", // from your experience URL in Creator Hub
});

if (!result.success) {
	console.error(`Open Cloud call failed: ${result.err.message}`);
	process.exit(1);
}

console.log(`${result.data.name} (${result.data.id})`);

Every method returns Promise<Result<T, OpenCloudError>>. Result is a discriminated union: result.success is true with the parsed response on result.data, or false with a structured error on result.err. No exception ever escapes a client method.

Available clients

Resource clients live on subpaths so unused features tree-shake out of your bundle.

| Subpath | Client | What it covers | | --------------------------------------- | ------------------------------- | ---------------------------------------------------------------------------- | | @bedrock-rbx/ocale/universes | UniversesClient | Universe metadata, social links, icon and thumbnail uploads. | | @bedrock-rbx/ocale/places | PlacesClient | Place metadata, .rbxl publishing, Luau execution tasks scoped to a place. | | @bedrock-rbx/ocale/game-passes | GamePassesClient | Game pass CRUD, icon upload, localized name and description updates. | | @bedrock-rbx/ocale/developer-products | DeveloperProductsClient | Developer product CRUD, icon upload, localized name and description updates. | | @bedrock-rbx/ocale/badges | BadgesClient | Badge CRUD and localized icon uploads. | | @bedrock-rbx/ocale/storage | StorageClient | Memory stores (sorted maps, queues) for live game state. | | @bedrock-rbx/ocale/luau-execution | LuauExecutionClient | Standalone Luau execution tasks with binary inputs and log streaming. | | @bedrock-rbx/ocale/locales | ROBLOX_CREATOR_LOCALES (data) | Reference list of locales Roblox supports for localized fields. |

Additional Open Cloud features (messaging, data stores, OAuth, groups, analytics) are not yet wrapped; they are tracked on the roadmap.

The package root (@bedrock-rbx/ocale) deliberately re-exports only shared utilities: Result, Page, OpenCloudError and its subclasses (ApiError, RateLimitError, NetworkError, ValidationError, and similar), and the OpenCloudClientOptions type. Resource clients are not on the root barrel.

Rate limiting and retries

The SDK queues every request behind a per-operation rate-limit bucket sourced from Roblox's published OpenAPI schema. You fire calls at whatever rate your code needs; the SDK paces them.

Retry behavior is idempotency-aware:

| Method kind | 429 (rate limit) | 5xx (server error) | | ----------- | ---------------- | ------------------ | | Create | Retry | Do not retry | | Read / List | Retry | Retry | | Update | Retry | Retry | | Delete | Retry | Retry |

Create operations skip 5xx retries because Roblox does not support idempotency keys and a duplicate retry would silently produce a second resource. If you can detect duplicates externally, opt back into 5xx retry on a per-call basis via retryableStatuses on the request options argument.

After retry attempts are exhausted, the final failure surfaces on result.err as the typed error that caused it (RateLimitError for 429s, ApiError for 5xx, NetworkError for transport-level faults, and so on).

Observability hooks (onRequest, onRetry, onRateLimit) accept callbacks on the client constructor for logging, metrics, or tracing integration.

Per-request configuration overrides

Client-level config is frozen on construction. Every method accepts an optional second RequestOptions argument that overrides config for a single call:

const client = new GamePassesClient({ apiKey: "main-key" });

const result = await client.create(parameters, {
	apiKey: "asset-upload-key", // different key for moderation safety
	timeout: 60_000,
});

This pattern fits multi-tenant tooling (different API keys per workspace), credential rotation (swap mid-batch), and isolating retry / timeout policies to specific calls.

Testing helpers

A @bedrock-rbx/ocale/testing subpath exports the same fakes the SDK's own integration tests use:

  • createFakeHttpClient(...) for swapping the HTTP transport with a recorded fake that validates request bodies against the vendored OpenAPI schema.
  • createFakeSend(...) for a lightweight scripted send-callback fake that records requests and replays responses for single-call tests, without schema validation.
  • createFakeSleep(...) for deterministic retry and rate-limit timing.
  • valid*Body fixtures (validGamePassBody, validPlaceBody, validUniverseBody, and similar) for synthesising realistic response payloads.

Pass the fake into any client via the httpClient and sleep parameters on OpenCloudClientOptions and assert against the captured requests.

Status, docs, and contributing

This package is pre-1.0 and under active development. Track scope and timing on the project board.

License

MIT (c) Christopher Buss.