MCPcopy Create free account
hub / github.com/avikalpg/byok-relay

github.com/avikalpg/byok-relay @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
37 symbols 81 edges 7 files 13 documented · 35% updated 2d ago★ 5417 open issues

Browse by type

Functions 35 Types & classes 2
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

byok-relay

Website: byokrelay.com | Hosted relay: relay.byokrelay.com

npm version npm downloads skills.sh OpenAPI 3.0 MCP Server Open in GitHub Codespaces Deploy on Railway Deploy with Vercel Run on Replit

Your users bring their own AI keys. byok-relay lets them use those keys straight from the browser — CORS handled, keys never in your code, costs on their bill.

Browser apps can't call api.openai.com or api.anthropic.com directly — CORS blocks them. The usual fix (a backend proxy) puts your users' keys — and your users' AI costs — on your tab. byok-relay flips this: each user gets a secure token; they store their own key; they pay for their own inference. You build the product.

Get started

Option A — Use our relay (zero setup):

https://relay.byokrelay.com

Free. Open CORS (any origin). Health check →

Option B — Self-host in 3 commands:

git clone https://github.com/avikalpg/byok-relay.git && cd byok-relay
echo "ENCRYPTION_SECRET=$(openssl rand -hex 32)" > .env
docker compose up -d   # relay running at http://localhost:3000

Or without Docker: npm install && npm start (requires Node 18+). Full quickstart →

Trust model: The managed relay holds the ENCRYPTION_SECRET. All request bodies (prompts, conversation history) transit through it in plaintext on the way to AI providers. It is suitable for prototypes, demos, and development — not production apps with paying users or sensitive data. For production: self-host. See SECURITY.md for full data residency details.

React hooks

For React apps (Lovable, Bolt.new, Vite, Next.js, Remix), install the hooks package:

npm install @byok-relay/react
import { useChat, useStreamingChat, useByokRelay } from '@byok-relay/react';

// Add BYOK chat to any React component
const { messages, sendMessage, isLoading } = useChat({
  appId: 'my-app',
  provider: 'openai',  // or 'anthropic', 'groq', 'mistral', 'openrouter'
  model: 'gpt-4o',
});

// Real-time streaming
const { streamingContent, isStreaming } = useStreamingChat({
  appId: 'my-app', provider: 'anthropic', model: 'claude-3-5-sonnet-20241022'
});

// Key storage UI
const { storeKey } = useByokRelay({ appId: 'my-app' });
await storeKey('openai', userEnteredKey);

See packages/react for full API docs.

Vue composables

For Vue 3 apps (Nuxt, Vite+Vue, Quasar), install the composables package:

npm install @byok-relay/vue
<script setup>
import { useByokRelay, useStreamingChat } from '@byok-relay/vue'

const relay = useByokRelay({ appId: 'my-app' })
const chat  = useStreamingChat({
  token: relay.token,
  provider: 'openai',  // or 'anthropic', 'groq', 'mistral', 'openrouter'
  model: 'gpt-4o-mini',
})
</script>

<template>


{{ m.role }}: {{ m.content }}




{{ chat.streamingContent.value }}


  <input @keydown.enter="e => chat.sendMessage(e.target.value)" />
  <button v-if="chat.isStreaming.value" @click="chat.stopStreaming()">Stop</button>
</template>

Four composables: useByokRelay (token + key storage), useChat (stateful chat), useStreamingChat (SSE streaming with stopStreaming()), useRelayHealth (polls /health).

See packages/vue for full API docs.

Svelte stores

npm install @byok-relay/svelte
<script>
  import { createByokRelayStore, createStreamingChatStore } from '@byok-relay/svelte';
  import { onMount } from 'svelte';

  const relay = createByokRelayStore({ appId: 'myapp' });
  const chat  = createStreamingChatStore({ appId: 'myapp', provider: 'openai' });

  onMount(() => {
    relay.register().catch(console.error);
  });
</script>

{#if $chat.isStreaming}


{$chat.streamingContent}<span>▋</span>


  <button on:click={chat.stopStreaming}>Stop</button>
{/if}

Four stores: createByokRelayStore · createChatStore · createStreamingChatStore · createRelayHealthStore. SvelteKit SSR-safe. See packages/svelte.

SolidJS reactive stores

npm install @byok-relay/solid
import { For, Show } from 'solid-js';
import { createByokRelayStore, createStreamingChatStore } from '@byok-relay/solid';

function App() {
  const relay = createByokRelayStore({ appId: 'my-app' });
  const chat  = createStreamingChatStore({ provider: 'openai', model: 'gpt-4o-mini' });

  async function send(text) {
    if (!relay.token()) await relay.register();
    await chat.sendMessage(text, relay.token());
  }

  return (
    <>
      <For each={chat.messages()}>{msg => 

{msg.role}: {msg.content}

}</For>
      <Show when={chat.streamingContent()}>

assistant: {chat.streamingContent()}▋

</Show>
    </>
  );
}

Also available: @byok-relay/react, @byok-relay/vue, @byok-relay/svelte

SolidJS reactive stores

npm install @byok-relay/solid
import { For, Show } from 'solid-js';
import { createByokRelayStore, createStreamingChatStore } from '@byok-relay/solid';

function App() {
  const relay = createByokRelayStore({ appId: 'my-app' });
  const chat  = createStreamingChatStore({ provider: 'openai', model: 'gpt-4o-mini' });

  async function send(text) {
    if (!relay.token()) await relay.register();
    await chat.sendMessage(text, relay.token());
  }

  return (
    <>
      <For each={chat.messages()}>{msg => 

{msg.role}: {msg.content}

}</For>
      <Show when={chat.streamingContent()}>

assistant: {chat.streamingContent()}▋

</Show>
    </>
  );
}

Also available: @byok-relay/react, @byok-relay/vue, @byok-relay/svelte, @byok-relay/angular

Angular injectable services

npm install @byok-relay/angular
import { NgFor } from '@angular/common';
import { Component, inject } from '@angular/core';
import { ByokRelayService, ChatService, provideByokRelay } from '@byok-relay/angular';

// app.config.ts
export const appConfig = {
  providers: [provideByokRelay({ relayUrl: 'https://relay.byokrelay.com' })],
};

// chat.component.ts
@Component({
  standalone: true,
  imports: [NgFor],
  template: `


{{ m.role }}: {{ m.content }}


    <button (click)="send('Hello!')">Send</button>
  `,
})
export class ChatComponent {
  relay = inject(ByokRelayService);
  chat  = inject(ChatService);

  async ngOnInit() { await this.relay.getOrRegister('my-app'); }
  async send(text: string) { await this.chat.sendMessage(text); }
}

Signals (Angular 16+), StreamingChatService (SSE + AbortController), RelayHealthService (polling), and Analog SSR support included. Full docs →

SolidJS reactive stores

npm install @byok-relay/solid
import { createByokRelayStore, createStreamingChatStore } from '@byok-relay/solid';

function App() {
  const relay = createByokRelayStore({ appId: 'my-app' });
  const chat  = createStreamingChatStore({ provider: 'openai', model: 'gpt-4o-mini' });

  async function send(text) {
    if (!relay.token()) await relay.register();
    await chat.sendMessage(text, relay.token());
  }

  return (
    <>
      <For each={chat.messages()}>{msg => 

{msg.role}: {msg.content}

}</For>
      <Show when={chat.streamingContent()}>

assistant: {chat.streamingContent()}▋

</Show>
    </>
  );
}

Also available: @byok-relay/react, @byok-relay/vue, @byok-relay/svelte, @byok-relay/angular

Angular injectable services

npm install @byok-relay/angular
import { Component, inject } from '@angular/core';
import { ByokRelayService, ChatService, provideByokRelay } from '@byok-relay/angular';

// app.config.ts
export const appConfig = {
  providers: [provideByokRelay({ relayUrl: 'https://relay.byokrelay.com' })],
};

// chat.component.ts
@Component({ template: `


{{ m.role }}: {{ m.content }}


  <button (click)="send('Hello!')">Send</button>
` })
export class ChatComponent {
  relay = inject(ByokRelayService);
  chat  = inject(ChatService);

  async ngOnInit() { await this.relay.getOrRegister('my-app'); }
  async send(text: string) { await this.chat.sendMessage(text); }
}

Signals (Angular 16+), StreamingChatService (SSE + AbortController), RelayHealthService (polling), and Analog SSR support included. Full docs →

Preact hooks (@byok-relay/preact)

For Preact apps, Astro component islands, or any Vite/Preact project:

npm install @byok-relay/preact
import { useStreamingChat, useByokRelay } from '@byok-relay/preact';

export function ChatIsland() {
  const { storeKey } = useByokRelay({
    relayUrl: import.meta.env.PUBLIC_RELAY_URL,
    appId: 'astro-app',
  });

  const { messages, streamingContent, isStreaming, sendMessage, stopStreaming } = useStreamingChat({
    relayUrl: import.meta.env.PUBLIC_RELAY_URL,
    appId: 'astro-app',
    provider: 'openai',
    model: 'gpt-4o-mini',
  });

  return (



      {messages.map((m, i) => 

<b>{m.role}:</b> {m.content}

)}
      {isStreaming && 

<em>{streamingContent}</em>

}
      <button onClick={() => sendMessage('Hello!')}>Send</button>
      {isStreaming && <button onClick={stopStreaming}>Stop</button>}



  );
}

SSR-safe (no window access during server render). Works with client:load, client:visible, and client:idle Astro directives. Full docs →

Vercel AI SDK (@byok-relay/vercel-ai)

For Next.js, SvelteKit, Nuxt, or any project using the Vercel AI SDK:

npm install @byok-relay/vercel-ai
import { createByokRelayProviderSync } from '@byok-relay/vercel-ai';
import { streamText, generateText, generateObject } from 'ai';

const provider = createByokRelayProviderSync({
  relayUrl: process.env.BYOK_RELAY_URL!,
  appId: 'my-app',
});

// One-time setup: store user's API key
await provider.storeKey('openai', userApiKey);

// Works with every AI SDK function
const result = streamText({
  model: provider.languageModel('openai/gpt-4o'),
  messages,
});
return result.toDataStreamResponse();

Supports generateText, streamText, generateObject, tool calling, vision inputs. Model IDs: 'openai/gpt-4o', 'anthropic/claude-3-5-sonnet-20241022', 'groq/llama3-70b-8192', bare model names (default: OpenAI). Full docs →

SolidJS reactive stores

npm install @byok-relay/solid
import { createByokRelayStore, createStreamingChatStore } from '@byok-relay/solid';

function App() {
  const relay = createByokRelayStore({ appId: 'my-app' });
  const chat  = createStreamingChatStore({ provider: 'openai', model: 'gpt-4o-mini' });

  async function send(text) {
    if (!relay.token()) await relay.register();
    await chat.sendMessage(text, relay.token());
  }

  return (
    <>
      <For each={chat.messages()}>{msg => 

{msg.role}: {msg.content}

}</For>
      <Show when={chat.streamingContent()}>

assistant: {chat.streamingContent()}▋

</Show>
    </>
  );
}

Also available: @byok-relay/react, @byok-relay/vue, @byok-relay/svelte, [@byok-relay/angular](https://

Core symbols most depended-on inside this repo

browse all functions →

Shape

Function 34
Class 2
Method 1

Languages

TypeScript100%

Modules by API surface

src/db.js13 symbols
src/providers.js9 symbols
examples/react-vite/src/relay.js8 symbols
examples/react-vite/src/App.jsx5 symbols
src/index.js2 symbols

For agents

$ claude mcp add byok-relay \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page