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

@oxy-hq/sdk

v1.0.0

Published

TypeScript SDK for interacting with Oxy data platform

Readme

Oxy TypeScript SDK

Official TypeScript/JavaScript SDK for interacting with the Oxy data platform.

Features

  • 🚀 Simple API - Easy-to-use client for fetching app data
  • 📊 Parquet Support - Read and query Parquet files using DuckDB-WASM
  • 🔒 Type-Safe - Full TypeScript support with comprehensive type definitions
  • 🌐 Universal - Works in both Node.js and browser environments
  • Fast - Optimized for performance with efficient data handling

Installation

npm install @oxy/sdk
# or
yarn add @oxy/sdk
# or
pnpm add @oxy/sdk

For Parquet file support, also install DuckDB-WASM:

npm install @duckdb/duckdb-wasm

Quick Start

Basic Usage

import { OxySDK } from "@oxy/sdk";

// Create SDK instance
const sdk = new OxySDK({
  apiKey: "your-api-key",
  projectId: "your-project-id",
  baseUrl: "https://api.oxy.tech",
});

// Load parquet files and query them
await sdk.loadFile("data/sales.parquet", "sales");
await sdk.loadFile("data/customers.parquet", "customers");

// Query with SQL - supports joins across multiple tables
const result = await sdk.query(`
  SELECT s.product, s.amount, c.name as customer_name
  FROM sales s
  JOIN customers c ON s.customer_id = c.id
  WHERE s.amount > 1000
  ORDER BY s.amount DESC
`);

console.log(result.rows);
await sdk.close();

Load App Data Automatically

import { OxySDK, createConfig } from "@oxy/sdk";

const sdk = new OxySDK(createConfig());

// Loads all data from the app and registers tables
await sdk.loadAppData("dashboard.app.yml");

// Query the loaded tables
const result = await sdk.query("SELECT * FROM my_table LIMIT 10");

Iframe Usage (PostMessage Authentication)

For embedding in iframes (e.g., v0.dev, sandboxed environments):

import { OxySDK } from "@oxy/sdk";

// SDK automatically requests API key from parent window
const sdk = await OxySDK.create({
  parentOrigin: "https://app.example.com",
  projectId: "your-project-uuid",
});

await sdk.loadAppData("dashboard.app.yml");
const result = await sdk.query("SELECT * FROM my_table LIMIT 10");

Parent window setup:

window.addEventListener("message", (event) => {
  if (event.data.type !== "OXY_AUTH_REQUEST") return;
  if (event.origin !== "https://your-iframe-app.com") return;

  event.source.postMessage(
    {
      type: "OXY_AUTH_RESPONSE",
      version: "1.0",
      requestId: event.data.requestId,
      apiKey: getUserApiKey(),
      projectId: "your-project-uuid",
      baseUrl: "https://api.oxy.tech",
    },
    event.origin,
  );
});

Environment Variables

export OXY_URL="https://api.oxy.tech"
export OXY_API_KEY="your-api-key"
export OXY_PROJECT_ID="your-project-uuid"
export OXY_BRANCH="main"  # optional

Use createConfig() to load from environment:

import { OxySDK, createConfig } from "@oxy/sdk";

const sdk = new OxySDK(createConfig());

React Integration

Using React Context (Recommended)

The SDK provides OxyProvider and useOxy hooks for easy integration:

import { OxyProvider, useOxy, createConfig } from "@oxy/sdk";
import { useEffect, useState } from "react";

// Wrap your app with OxyProvider
function App() {
  return (
    <OxyProvider config={createConfig()}>
      <Dashboard />
    </OxyProvider>
  );
}

// Access SDK in child components
function Dashboard() {
  const { sdk, isLoading, error } = useOxy();
  const [data, setData] = useState(null);

  useEffect(() => {
    if (sdk) {
      sdk
        .loadAppData("dashboard.app.yml")
        .then(() => sdk.query("SELECT * FROM my_table LIMIT 100"))
        .then(setData);
    }
  }, [sdk]);

  if (isLoading) return <div>Initializing SDK...</div>;
  if (error) return <div>Error: {error.message}</div>;
  if (!data) return <div>Loading data...</div>;

  return (
    <div>
      <h1>Dashboard</h1>
      <table>
        <thead>
          <tr>
            {data.columns.map((col) => (
              <th key={col}>{col}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {data.rows.map((row, i) => (
            <tr key={i}>
              {row.map((cell, j) => (
                <td key={j}>{String(cell)}</td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

Iframe with PostMessage Auth

import { OxyProvider, useOxySDK } from "@oxy/sdk";

function App() {
  return (
    <OxyProvider useAsync config={{ parentOrigin: "https://app.example.com" }}>
      <Dashboard />
    </OxyProvider>
  );
}

function Dashboard() {
  const sdk = useOxySDK(); // Throws if not ready
  const [data, setData] = useState(null);

  useEffect(() => {
    sdk
      .loadFile("data/sales.parquet", "sales")
      .then(() => sdk.query("SELECT * FROM sales LIMIT 100"))
      .then(setData);
  }, [sdk]);

  return <div>{/* render data */}</div>;
}

Without Context (Alternative)

import { OxySDK, createConfig } from '@oxy/sdk';
import { useEffect, useState } from 'react';

const sdk = new OxySDK(createConfig());

function Dashboard() {
  const [data, setData] = useState(null);

  useEffect(() => {
    sdk.loadAppData('dashboard.app.yml')
      .then(() => sdk.query('SELECT * FROM my_table LIMIT 100'))
      .then(setData);
  }, []);

  return <div>{/* render data */}</div>;
}

Use with v0 and Sandbox Services

For AI Assistants (v0.dev, Cursor, etc.): See .v0/rules.md and .cursorrules for integration guidelines.

import { OxySDK, createConfig } from "@oxy/sdk";

const sdk = new OxySDK(createConfig());

export async function getDashboardData() {
  await sdk.loadAppData("dashboard.app.yml");

  return await sdk.query(`
    SELECT s.*, c.name as customer_name
    FROM sales s
    LEFT JOIN customers c ON s.customer_id = c.id
    ORDER BY s.date DESC
    LIMIT 100
  `);
}

export function getChartUrl() {
  return sdk.getClient().getFileUrl("charts/sales-overview.png");
}

API Reference

OxySDK (Unified Interface)

The OxySDK class combines OxyClient and ParquetReader into a single, easy-to-use interface.

constructor(config: OxyConfig)

Creates a new SDK instance.

static async create(config?: Partial<OxyConfig>): Promise<OxySDK>

Creates an SDK instance with async configuration (supports postMessage auth).

const sdk = await OxySDK.create({
  parentOrigin: "https://app.example.com",
  projectId: "your-project-id",
});

async loadFile(filePath: string, tableName: string): Promise<void>

Loads a Parquet file from Oxy and registers it for SQL queries.

await sdk.loadFile("data/sales.parquet", "sales");

async loadFiles(files: Array<{filePath: string, tableName: string}>): Promise<void>

Loads multiple Parquet files at once.

await sdk.loadFiles([
  { filePath: "data/sales.parquet", tableName: "sales" },
  { filePath: "data/customers.parquet", tableName: "customers" },
]);

async loadAppData(appPath: string): Promise<DataContainer | null>

Loads all data from an app's data container. Uses container keys as table names.

const data = await sdk.loadAppData("dashboard.app.yml");
// Now query the tables using their container keys
const result = await sdk.query("SELECT * FROM my_table");

async query(sql: string): Promise<QueryResult>

Executes a SQL query against loaded data.

const result = await sdk.query("SELECT * FROM sales WHERE amount > 1000");

async getAll(tableName: string, limit?: number): Promise<QueryResult>

Gets all data from a loaded table.

const data = await sdk.getAll("sales", 100);

async getSchema(tableName: string): Promise<QueryResult>

Gets schema information for a loaded table.

async count(tableName: string): Promise<number>

Gets row count for a loaded table.

getClient(): OxyClient

Returns the underlying OxyClient for advanced operations.

const apps = await sdk.getClient().listApps();

getReader(): ParquetReader

Returns the underlying ParquetReader for advanced operations.

async close(): Promise<void>

Closes and cleans up all resources.

React Hooks

OxyProvider

Provider component that initializes and provides OxySDK to child components.

Props:

  • config?: Partial<OxyConfig> - SDK configuration
  • useAsync?: boolean - If true, uses async initialization (supports postMessage auth)
  • appPath?: string - Optional app path to load initial app data upon initialization
  • files?: Record<string, string> - Optional initial files to preload as a mapping of table name to file path
  • onReady?: (sdk: OxySDK) => void - Called when SDK is initialized
  • onError?: (error: Error) => void - Called on initialization error
  • loadingFallback?: ReactNode - Rendered while the SDK is initializing (replaces children during load)
  • errorFallback?: ReactNode | ((error: Error) => ReactNode) - Rendered when initialization fails; can be a node or a render function that receives the error
<OxyProvider
  config={createConfig()}
  loadingFallback={<div>Loading SDK...</div>}
  errorFallback={(error) => <div>Failed to initialize: {error.message}</div>}
>
  <YourApp />
</OxyProvider>

useOxy()

Hook to access SDK, loading state, and errors.

const { sdk, isLoading, error } = useOxy();

Returns:

  • sdk: OxySDK | null - The SDK instance (null if not ready)
  • isLoading: boolean - True while initializing
  • error: Error | null - Initialization error if any

useOxySDK()

Hook that returns SDK directly or throws if not ready. Useful when you know SDK should be initialized.

const sdk = useOxySDK(); // Throws if not ready

Advanced: OxyClient

For advanced use cases, access the underlying client via sdk.getClient():

const client = sdk.getClient();
await client.listApps();
await client.getDisplays("my-app.app.yml");
const blob = await client.getFile("path/to/file.parquet");

Advanced: ParquetReader

For advanced use cases, access the underlying reader via sdk.getReader():

const reader = sdk.getReader();
await reader.registerParquet(customBlob, "custom_table");

Or use standalone:

import { ParquetReader } from "@oxy/sdk";

const reader = new ParquetReader();
await reader.registerParquet(blob1, "table1");
await reader.registerParquet(blob2, "table2");

const result = await reader.query("SELECT * FROM table1 JOIN table2 ON ...");
await reader.close();

Environment Variables

  • OXY_URL - Base URL of the Oxy API (required)
  • OXY_API_KEY - API key for authentication (required)
  • OXY_PROJECT_ID - Project UUID (required)
  • OXY_BRANCH - Branch name (optional)

Examples

See the examples directory for more detailed examples:

Building and Publishing

# Install dependencies
npm install

# Build the SDK
npm run build

# Type check
npm run typecheck

# Lint
npm run lint

# Publish to npm (beta)
npm run publish:beta

# Publish to npm (latest)
npm run publish:latest

License

MIT

Support

For issues and questions, please visit GitHub Issues.

Local development with v0 or cloud service

  • Disable the local network access check [flag](chrome ://flags/#local-network-access-check)