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

@parel-cloud/node

v0.1.1

Published

Parel SDK for JavaScript/TypeScript. 100+ AI models, GPU rental (BYOM), compare, and credits via a single OpenAI-compatible API. Official client for parel.cloud.

Downloads

42

Readme


Install

npm install @parel-cloud/node openai

Hello world

import { Parel } from "@parel-cloud/node";

const parel = new Parel(); // reads PAREL_API_KEY
const openai = await parel.openai;

const chat = await openai.chat.completions.create({
  model: "qwen3.5-72b",
  messages: [{ role: "user", content: "Merhaba, bana bir haiku yaz." }],
});
console.log(chat.choices[0].message.content);

Sign up at parel.cloud and every new account gets $1 free credit. That is a few thousand chat tokens, a handful of Flux images, or a one-minute Wan video, on us.


Why @parel-cloud/node


How it works

Your app calls @parel-cloud/node. The SDK speaks HTTPS + Bearer auth to api.parel.cloud. Parel routes the request to the right provider, enforces your budget, handles PII, and returns an OpenAI-shaped response. The SDK never holds vendor keys. You never glue five client libraries together.


Providers


What you get

| Namespace | What it does | Return mode | |-------------------|-------------------------------------------------------------------|----------------| | parel.openai | Chat, embeddings, moderations, vision, tools, streaming, speech | Sync, streamed | | parel.images | Image generation and edits | Polled, sync | | parel.videos | Text-to-video, image-to-video | Polled, sync | | parel.audio | TTS, music, transcription | Polled, sync | | parel.gpu | BYOM deploy lifecycle, inference, billing, events, tiers, prefetch| Polled | | parel.compare | Multi-model head-to-head, conversations, winner marking | Polled | | parel.models | Catalogue list and detail | Sync | | parel.credits | Budget snapshot in USD | Sync | | parel.tasks | Poll, wait, list, cancel async jobs | Sync |


Quickstart

Chat (OpenAI pass-through)

import { Parel } from "@parel-cloud/node";

const parel = new Parel({ apiKey: process.env.PAREL_API_KEY });
const openai = await parel.openai;

const res = await openai.chat.completions.create({
  model: "qwen3.5-72b",
  messages: [{ role: "user", content: "Why is the sky blue?" }],
});

Streaming

const stream = await openai.chat.completions.create({
  model: "qwen3.5-72b",
  messages: [{ role: "user", content: "Count to 5." }],
  stream: true,
});
for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta?.content ?? "");

Tools and vision

await openai.chat.completions.create({
  model: "qwen3.5-vl-32b",
  messages: [
    {
      role: "user",
      content: [
        { type: "text", text: "What's in this image?" },
        { type: "image_url", image_url: { url: "https://example.com/cat.jpg" } },
      ],
    },
  ],
  tools: [{ type: "function", function: { name: "search_web", parameters: { type: "object", properties: { q: { type: "string" } } } } }],
});

Images

const image = await parel.images.generate({
  model: "flux-schnell",
  prompt: "A minimalist watercolor of Istanbul at dawn, Bosphorus in fog",
  size: "1024x1024",
  onTick: (t) => console.log(`[${t.progress}%] ${t.status}`),
});
// image.result.data[0].url

Fire-and-forget:

const { task_id } = await parel.images.generate({ model: "flux-schnell", prompt: "...", async: true });
const done = await parel.tasks.waitFor(task_id);

Video

const video = await parel.videos.generate({
  model: "wan-2.6-t2v",
  prompt: "A robot watering a cherry tree at sunset",
  duration: 5,
  resolution: "1280x720",
  timeoutMs: 30 * 60_000,
});

Speech and transcription

// TTS
await parel.audio.speech({ model: "elevenlabs-tts", input: "Parel'e hoş geldin", voice: "alloy" });

// STT (Whisper Turbo, Turkish-friendly)
const t = await parel.audio.transcribe({ model: "whisper-large-v3-turbo", file: base64Wav, language: "tr" });
console.log(t.text);

Deploy a Hugging Face model on a rented GPU (BYOM)

const hf = await parel.gpu.validateHuggingFace("meta-llama/Llama-3.1-8B-Instruct");
// hf.recommended_gpu_tier === "rtx4090_24gb"

await parel.gpu.prefetch("meta-llama/Llama-3.1-8B-Instruct"); // optional, warm S3

const dep = await parel.gpu.create({
  huggingface_id: "meta-llama/Llama-3.1-8B-Instruct",
  gpu_tier: hf.recommended_gpu_tier ?? "rtx4090_24gb",
  idle_timeout_minutes: 15,
  budget_limit_usd: 5,
});

await parel.gpu.waitForRunning(dep.id, { onTick: (d) => console.log(d.status) });

const answer = await parel.gpu.chat(dep.id, {
  messages: [{ role: "user", content: "Write a haiku about Istanbul" }],
  max_tokens: 120,
});

await parel.gpu.stop(dep.id); // or parel.gpu.delete(dep.id)

Parel picks the cheapest available GPU across RunPod, Modal, and Vast.ai, handles TGI vs vLLM selection per architecture, enforces your budget cap, and refunds credits on crash loops. You watch deployment.status and call chat.

Multi-model compare

const run = await parel.compare.run({
  models: ["qwen3.5-72b", "gpt-4o-mini", "claude-3-5-sonnet", "gemini-2.5-pro"],
  prompt: "Summarize in 3 bullets: why KVKK compliance matters for Turkish SaaS.",
  timeoutMs: 10 * 60_000,
});
console.log(run.results);

Credits and budget

const snap = await parel.credits.get();
if (snap.remaining_usd < 1) console.log("top up: https://parel.cloud/billing");

Cancel a running task

const cancel = await parel.tasks.cancel(taskId);
console.log(`refunded $${cancel.refund_amount_usd}`);

Migrate from OpenAI in 30 seconds

- import OpenAI from "openai";
- const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
+ import { Parel } from "@parel-cloud/node";
+ const parel = new Parel({ apiKey: process.env.PAREL_API_KEY });
+ const openai = await parel.openai;

Every OpenAI call keeps working. You gain Qwen, Llama, DeepSeek, Claude, Gemini, Flux, Kling, Veo, Whisper, BYOM GPU, compare, credits, and tasks.


Error handling

import {
  ParelError,
  ParelAuthenticationError,
  ParelBudgetExceededError,
  ParelRateLimitError,
  ParelConflictError,
  ParelNotFoundError,
  ParelTimeoutError,
  ParelValidationError,
} from "@parel-cloud/node";

try {
  await parel.images.generate({ model: "flux-schnell", prompt: "cat" });
} catch (err) {
  if (err instanceof ParelBudgetExceededError) {
    // 402, top up at parel.cloud/billing
  } else if (err instanceof ParelRateLimitError) {
    await sleep((err.retryAfter ?? 1) * 1000);
  } else if (err instanceof ParelConflictError && err.code === "task_not_cancellable") {
    // cannot cancel, task already completed
  } else if (err instanceof ParelError) {
    console.error(err.status, err.code, err.message, err.requestId);
  } else {
    throw err;
  }
}

Every error carries the OpenAI-compatible envelope: code, type, message, requestId, HTTP status. Attach requestId to support tickets for faster triage.


Configuration

new Parel({
  apiKey: "pk-live-...",              // or PAREL_API_KEY env
  baseUrl: "https://api.parel.cloud", // override for staging or self-hosted
  timeoutMs: 60_000,                  // per-request timeout
  maxRetries: 2,                      // on 429, 5xx, network; idempotent verbs only
  fetch: globalThis.fetch,            // polyfill slot
  userAgent: "my-app/1.0",
});

Retry policy. GET, HEAD, DELETE, PUT retry up to maxRetries on 429, 5xx, ParelConnectionError, ParelTimeoutError. POST and PATCH never auto-retry, so generation calls are never double-charged. Backoff is exponential (500ms, 1s, 2s, 4s, 8s cap) with jitter.

AbortController. Every namespace helper accepts an AbortSignal. Cancel long polls cleanly:

const ac = new AbortController();
setTimeout(() => ac.abort(), 60_000);
await parel.images.generate({ model, prompt, signal: ac.signal });

Supported models

| Family | Examples | |-----------------|------------------------------------------------------------------------------------------| | LLM (open) | Qwen3.5 7B/32B/72B, Llama 3.3 70B, DeepSeek V3 671B, DeepSeek R1, Gemma 4 27B, Mistral Large, Nemotron 70B, Phi-4 | | LLM (closed) | GPT-4o, GPT-4o-mini, GPT-o1, Claude 3.5 Sonnet, Claude 4 Opus, Gemini 2.5 Pro, Gemini 3.1, Grok 4 | | Vision | Qwen3.5-VL 32B, GPT-4o vision, Claude vision, Gemini vision | | Image | Flux Schnell / Dev / Pro, SDXL Turbo, Recraft V4, Gemini 3.1 Nano Image, DALL-E 3 | | Video | Wan 2.6, Kling 3, Veo 3.1, Seedance 1.5, Hailuo 2 | | TTS | ElevenLabs v2, Orpheus Turkish, Kokoro Turkish, Chatterbox | | STT | Whisper Large v3 Turbo, Whisper Large v3, Faster-Whisper | | Embeddings | text-embedding-3-small / large, bge-large, qwen3-embed | | Reranking | bge-reranker, jina-reranker | | Moderation | omni-moderation-latest |

Live catalogue and pricing: parel.cloud/models.


Pricing

Prepaid pay-as-you-go in USD. No subscription. No tiers.

  • Sign-up bonus: $1 free credit on every new account.
  • Top-up presets: $5 / $20 / $50 / $100 / $500 via Lemon Squeezy.
  • Batch tier: 50% discount for jobs that can wait up to 24 hours.
  • BYOM billing is per-second, metered at your chosen GPU tier.

Full pricing: parel.cloud/pricing.


FAQ

Do I need to install openai? Only for parel.openai.*. Images, videos, audio, BYOM, compare, credits, and tasks namespaces work without it.

Does it work in the browser? v0.1 is Node-first (18+). Use a server proxy for browsers today. Never ship API keys to clients. A browser entry point is planned for v0.2.

Is streaming supported? Yes for chat and completions (via parel.openai). Generations use polling, not SSE, in v0.1.

Is there a Python SDK? Yes, coming as @parel-cloud/python on PyPI. Track at github.com/parel-cloud/parel-python.

How do I self-host or point at staging? Pass baseUrl to the Parel constructor. Every path is /v1/....

Is it KVKK or GDPR compliant? Parel ships an opt-in KVKK mode: PII masking + Turkey-resident data. See docs.parel.cloud/kvkk.

How do I report a bug? github.com/parel-cloud/parel-node/issues. Include your requestId from the error.


Roadmap

  • v0.2 - Browser entry, @parel-cloud/react hooks, multipart STT, SSE streaming for generations
  • v0.3 - Webhooks, batch tier helpers, OpenAPI-codegen types
  • v1.0 - Stable surface, semver guarantees

Track releases: github.com/parel-cloud/parel-node/releases.


Links

License

MIT © Parel Cloud / Aleonis Teknoloji Ltd. Şti.