# Dbrij Apps, SDKs and packages

Get Dbrij on iPhone, Android, Mac, Windows, Linux and the browser, and build it into your own product with every SDK and package: Node, Python, Go, Swift, Kotlin, Flutter and React Native SDKs, the dbrij command line, plugins and drop in scripts.

Canonical page: https://dbrij.com/apps

## Every stack covered

- TypeScript 10 packages
- JavaScript 8 packages
- Node.js 5 packages
- Browsers 11 packages
- React Native 4 packages
- Capacitor 3 packages
- Python 1 package
- Go 3 packages
- Swift 2 packages
- iOS 6 packages
- Kotlin 2 packages
- Android 6 packages
- Dart 4 packages
- Flutter 4 packages
- Docker 1 package
- Kubernetes 1 package
- Command line 1 package

## Every SDK and package

### @dbrij/secrets

Load an environment's secrets into a Node app with a machine token and open them on your own server.

SDK · TypeScript · npm · Runs on Node 20+

- Values are sealed with keys Dbrij never holds and opened on your server
- One request per load; refresh sends the last ETag, so an unchanged environment costs a tiny 304
- Keeps serving the last good copy for an hour when Dbrij cannot be reached, and never hides a refusal
- watch follows the environment and calls you when values change
- A machine with write access can set and delete, sealed here before anything leaves
- Key management: encrypt, decrypt, sign and verify with keys that never leave Dbrij

Install

```
npm install @dbrij/secrets
```

Quick start

```
import { DbrijSecrets } from '@dbrij/secrets';// Reads DBRIJ_SECRETS_TOKEN and DBRIJ_SECRETS_ENV from the environment.const secrets = new DbrijSecrets({ environment: 'production' });await secrets.load();const databaseUrl = secrets.get('DATABASE_URL');secrets.injectEnv(); // or put every value into process.env
```

### dbrij-secrets

Load an environment's secrets into a Python app with a machine token and open them on your own server.

SDK · Python · PyPI · Runs on Python 3.9+

- Values are opened on your server; only the first two parts of the token are ever sent
- refresh asks with the last ETag, so an unchanged environment costs one small request
- Serves the last good copy for an hour when Dbrij cannot be reached
- watch asks again every 30 seconds in a background thread and calls you on a change
- Login keys sign in with the identity your CI or cloud already has
- Key management: encrypt, decrypt, sign and verify with keys that never leave Dbrij

Install

```
pip install dbrij-secrets
```

Quick start

```
from dbrij_secrets import DbrijSecrets# Reads DBRIJ_SECRETS_TOKEN and DBRIJ_SECRETS_ENV from the environment.secrets = DbrijSecrets(environment="production")secrets.load()database_url = secrets.get("DATABASE_URL")secrets.inject_env()  # or put every value into os.environ
```

### github.com/DbrijHQ/secrets-go

Load an environment's secrets into a Go service with a machine token and open them on your own server.

SDK · Go · Go module · Runs on Go 1.24+

- Standard library only, and safe to share across goroutines
- Refresh asks with the last ETag, so an unchanged environment costs one small request
- Serves the last good copy for an hour when Dbrij cannot be reached; NoFailSoft turns that off
- Watch follows the version stream and calls you when values change
- Set and Delete seal values here and are refused if the environment moved meanwhile
- Key management: encrypt, decrypt, sign and verify with keys that never leave Dbrij

Install

```
go get github.com/DbrijHQ/secrets-go
```

Quick start

```
import dbrijsecrets "github.com/DbrijHQ/secrets-go"// Reads DBRIJ_SECRETS_TOKEN and DBRIJ_SECRETS_ENV from the environment.secrets, err := dbrijsecrets.New(dbrijsecrets.Options{Environment: "production"})if err != nil {	log.Fatal(err)}if _, err := secrets.Load(ctx); err != nil {	log.Fatal(err)}databaseURL, _ := secrets.Get("DATABASE_URL")
```

### Dbrij Secrets operator

A Kubernetes operator that keeps a Secret in your cluster in step with an environment in Dbrij Secrets.

Kubernetes operator · Go · Container image · Runs on Kubernetes, linux/amd64, linux/arm64

- A DbrijSecret names the project, environment, folders and the Secret to write
- Values are opened inside the cluster with the machine's key half, which never reaches Dbrij
- Asks with the last version it has, so no change means one small request and no write
- Restarts the workloads you list when values change, no more often than the cooldown
- Never takes over a Secret it did not make, and never writes a value it could not open
- Signs in with a machine token or with its own service account

Install

```
kubectl apply -f https://dbrij.com/secrets-operator/0.1.0/install.yaml
```

Quick start

```
apiVersion: secrets.dbrij.com/v1alpha1kind: DbrijSecretmetadata:  name: api  namespace: shopspec:  project: shop  environment: production  target:    name: api-secrets  auth:    tokenSecretRef: { name: dbrij-token, key: token }  rolloutRestart:    - { kind: Deployment, name: api }
```

### Dbrij relay

A small relay you run inside a private network so Secrets server access can reach its servers and databases without opening a port.

Service you run · Go · Container image · Runs on Docker, linux/amd64, linux/arm64

- Never listens on a port: it asks Dbrij for work over HTTPS and connects out
- Dials only the hosts and ports its allow list names
- Never receives a password or key; the access gateway signs in through it
- One static binary on the Go standard library, running as a non root user
- Its token only asks for work, and replacing it in Dbrij stops the old one at once

Install

```
docker run -d --name dbrij-relay --restart unless-stopped \  -e DBRIJ_RELAY_TOKEN=dbsr_... \  -e DBRIJ_RELAY_API=https://api.dbrij.com/api/v1 \  -e DBRIJ_RELAY_ALLOW=10.0.0.0/8:22,10.0.0.0/8:5432 \  ghcr.io/dbrijhq/dbrij-secrets-relay:0.1.0
```

Quick start

```
# relay.env, readable only by you:#   DBRIJ_RELAY_TOKEN=dbsr_...#   DBRIJ_RELAY_ALLOW=10.0.0.0/8:22,10.0.0.0/8:5432docker run -d --name dbrij-relay --restart unless-stopped \  --env-file relay.env \  ghcr.io/dbrijhq/dbrij-secrets-relay:0.1.0
```

### @dbrij/ship

The Ship core for JavaScript apps: feature flags, remote config, the kill switch and the update decision in one check in.

SDK · TypeScript · npm · Runs on React Native, Capacitor, Node, Any runtime with fetch

- One check in returns flags, config, the kill switch and any update
- Caches the last good answer so getFlag and getConfig work offline; the kill switch is never cached
- A stable random device id buckets rollouts, and Ship stores only its hash
- signal reports release health so a rollout can pause itself
- disabled honours an opt out: nothing is sent at all
- Drives the React Native and Capacitor plugins for code push

Install

```
npm i @dbrij/ship
```

Quick start

```
import { createShip } from '@dbrij/ship';import AsyncStorage from '@react-native-async-storage/async-storage'; // or any getItem/setItem pairconst ship = createShip({  appKey: 'shp_...',  channel: 'production',  binaryVersion: '1.2.0',  platform: 'android',  storage: AsyncStorage,});const { killSwitch } = await ship.checkIn();if (!killSwitch && ship.getFlag('new_checkout')) {  // ...}const apiUrl = ship.getConfig('api_url', 'https://fallback.example.com');
```

### @dbrij/ship-react-native

Code push for React Native and Expo: signed bundle updates, verified on the device, with a boot canary that reverts a bad bundle.

Plugin · TypeScript · npm · Runs on React Native 0.71+, iOS 13+, Android (updates on Android 13 and later), Expo development and store builds

- Checks the sha256 and the ed25519 signature against your pinned keys before a byte is applied
- A bundle that crashes before notifyAppReady is reverted on the next start and reported
- Staged updates apply on the next launch; mandatory ones restart at once
- The Expo config plugin points the release build at the newest verified bundle on every prebuild
- Fails closed on Android below 13, and the store bundle is always the fallback

Install

```
npm i @dbrij/ship @dbrij/ship-react-nativecd ios && pod install
```

Quick start

```
import { createShip } from '@dbrij/ship';import { notifyAppReady, syncShipUpdates } from '@dbrij/ship-react-native';import AsyncStorage from '@react-native-async-storage/async-storage';const ship = createShip({ appKey: 'shp_...', channel: 'production', binaryVersion: '1.2.0', platform: Platform.OS, storage: AsyncStorage });// In your root component, once the first screen mounts:useEffect(() => {  notifyAppReady(ship)    .then(() => syncShipUpdates(ship, { signPublicKeys: ['BASE64_KEY_FROM_DASHBOARD'] }))    .catch(() => undefined);}, []);
```

### @dbrij/ship-capacitor

Live updates for Capacitor and Ionic apps: your built web assets as a signed bundle, verified on the device, with boot canary rollback.

Plugin · TypeScript · npm · Runs on Capacitor 5+, Ionic, iOS 13+, Android (updates on Android 13 and later)

- A release is a zip of your built web assets, uploaded on the Ship dashboard
- Verifies the sha256 and ed25519 signature against your pinned keys before unpacking, with a zip slip guard
- A bundle that never reaches notifyAppReady is reverted on the next start and reported
- Staged updates serve on the next launch; mandatory ones reload at once
- The app's own assets stay as the fallback that cannot be touched

Install

```
npm i @dbrij/ship @dbrij/ship-capacitornpx cap sync
```

Quick start

```
import { createShip } from '@dbrij/ship';import { notifyAppReady, syncShipUpdates } from '@dbrij/ship-capacitor';import { Preferences } from '@capacitor/preferences';const ship = createShip({  appKey: 'shp_...',  channel: 'production',  binaryVersion: '1.2.0',  platform: 'capacitor',  storage: {    getItem: async (k) => (await Preferences.get({ key: k })).value,    setItem: async (k, v) => Preferences.set({ key: k, value: v }),  },});await notifyAppReady(ship);await syncShipUpdates(ship, { signPublicKeys: ['BASE64_KEY_FROM_DASHBOARD'] });
```

### dbrij_ship

Ship for Flutter and Dart: feature flags, remote config, a kill switch and store version policy, plus asset packs you change without a store release.

SDK · Dart · pub.dev · Runs on Dart 3+, Flutter on iOS and Android

- One check in resolves flags, config, the kill switch and the store version verdict for each device
- Answers from the cache offline, and your shipped fallbacks run on first launch
- Asset packs: files your app reads at runtime, staged and rolled back like any release
- Packs are checked against their sha256 and a signature before they are unpacked
- signal and runGuarded report release health so a rollout can pause itself

Install

```
flutter pub add dbrij_ship
```

Quick start

```
import 'package:dbrij_ship/dbrij_ship.dart';final ship = Ship(  appKey: 'shp_…',  channel: 'production',  binaryVersion: packageInfo.version,  platform: Platform.isIOS ? 'ios' : 'android',  storage: PrefsShipStorage(), // any getItem/setItem pair);try {  await ship.checkIn();} catch (_) {}if (ship.getFlag('new_checkout')) { /* … */ }final banner = ship.getConfig('banner', '');
```

### dbrij_ship_rfw

Server driven Flutter screens for Ship: Remote Flutter Widgets blobs that ride in asset packs and roll out like any release.

Plugin · Dart · pub.dev · Runs on Flutter 3.16+

- A blob composes only widgets your app registered, so nothing downloaded runs as code
- A required local fallback renders on first launch, offline and under the kill switch
- Events a blob raises go to your own Dart code
- publishShipValues lets blobs read your flags and config
- A pack tool compiles .rfwtxt and refuses anything executable

Install

```
flutter pub add dbrij_ship_rfw
```

Quick start

```
import 'package:dbrij_ship_rfw/dbrij_ship_rfw.dart';final ui = ShipRemoteUi(assets: assets, widgets: createMaterialWidgets());await assets.restore();await ui.loadAll(['checkout']);ui.publishShipValues(ship);ShipRemoteWidget(  ui: ui,  name: 'checkout',  fallback: (context) => const LocalCheckoutScreen(),  onEvent: (name, args) {    if (name == 'checkout.begin') startCheckout(args);  },)
```

### resolve-widget.js

A support bubble for any website: one script tag opens your Resolve desk in a panel on the page.

Script for your site · JavaScript · Served by Dbrij · Runs on Browsers

- A floating bubble opens the desk's portal; your page's styles are never touched
- Signed users go straight in with a user hash made on your server
- Tickets start prefilled with your signed in user
- Matches your page's light or dark theme and the desk's brand colour
- window.DbrijResolve.identify sets the user after your own sign in

Install

```
<script src="https://resolve.dbrij.com/resolve-widget.js" data-desk="rk_..." defer></script>
```

Quick start

```
<script src="https://resolve.dbrij.com/resolve-widget.js"  data-desk="rk_..."  data-email="ada@example.com"  data-user-hash="HMAC_FROM_YOUR_SERVER"  defer></script>
```

### @dbrij/resolve

Resolve inside Capacitor, Ionic, Cordova and web apps: the support screen, signed sign in and the unread badge.

SDK · TypeScript · npm · Runs on Capacitor, Ionic, Cordova, Browsers, Any runtime with fetch

- openResolve shows the desk's own support center: tickets, screenshots, replies and fixes to confirm
- Signed sign in with a user hash from your server, or an emailed code once per device
- unread gives the badge count and keeps the session in your storage
- Brand, answers and hours come from the desk, with no app update
- Zero dependencies

Install

```
npm install @dbrij/resolve
```

Quick start

```
import { openResolve } from '@dbrij/resolve';const screen = openResolve({  desk: 'rk_...',  identity: { email, name, externalId, userHash }, // userHash from your server  onClose: () => {},});// screen.close() from your own back button
```

### @dbrij/resolve-react-native

Resolve for React Native and Expo: your support desk as a screen in your app, with signed sign in, screenshots on tickets and the unread badge.

SDK · TypeScript · npm · Runs on React Native 0.71+, Expo, React 18+

- ResolveSupport is the desk as a screen in your app
- useResolveUnread checks on mount, on return to the front and every minute while in front
- Signed sign in with a user hash from your server
- Customers attach screenshots to their tickets
- resolveSignOut ends the session from your own sign out

Install

```
npm install @dbrij/resolve-react-native react-native-webview
```

Quick start

```
import AsyncStorage from '@react-native-async-storage/async-storage';import { ResolveSupport } from '@dbrij/resolve-react-native';export function HelpScreen({ navigation }) {  return (    <ResolveSupport      desk="rk_..."      identity={{ email: user.email, name: user.name, externalId: user.id, userHash: user.resolveHash }}      storage={AsyncStorage}      onClose={() => navigation.goBack()}    />  );}
```

### DbrijResolve

Resolve for iOS in Swift: your support desk as a screen in SwiftUI or UIKit, with signed sign in, screenshots on tickets and the unread badge.

SDK · Swift · Swift Package Manager · Runs on iOS 15+, Swift 5.9+

- ResolveSupportView for SwiftUI and ResolveSupportViewController for UIKit
- ResolveClient.unread gives the badge count, with the session kept in the Keychain
- Signed sign in with a user hash from your server
- Screenshots on tickets from the photo library or the camera
- No dependencies

Install

```
.package(url: "https://github.com/DbrijHQ/resolve-ios", from: "0.1.0")
```

Quick start

```
import DbrijResolvelet me = ResolveIdentity(email: user.email, externalId: user.id, userHash: user.resolveHash).sheet(isPresented: $showHelp) {    ResolveSupportView(desk: "rk_...", identity: me) { showHelp = false }}
```

### com.github.DbrijHQ:resolve-android

Resolve for Android in Kotlin: your support desk as a screen in your app, with signed sign in, screenshots on tickets and the unread badge.

SDK · Kotlin · JitPack · Runs on Android 6+ (API 23)

- ResolveSupport.open shows the desk as a screen that closes with its button or the back gesture
- ResolveClient.unread gives the badge count from a coroutine
- Signed sign in with a user hash from your server
- Screenshots and documents attach through the system picker

Install

```
// settings.gradle.kts, under dependencyResolutionManagement.repositoriesmaven { url = uri("https://jitpack.io") }// app/build.gradle.ktsimplementation("com.github.DbrijHQ:resolve-android:0.1.0")
```

Quick start

```
import com.dbrij.resolve.ResolveIdentityimport com.dbrij.resolve.ResolveSupportResolveSupport.open(    context,    desk = "rk_...",    identity = ResolveIdentity(email = user.email, externalId = user.id, userHash = user.resolveHash),)
```

### dbrij_resolve

Resolve for Flutter: your support desk as a screen in your app, with signed sign in, screenshots on tickets and the unread badge.

SDK · Dart · pub.dev · Runs on Flutter 3.16+, iOS, Android

- ResolveSupport is the desk as a widget you push like any screen
- ResolveClient.unread gives the badge count
- Signed sign in with a user hash from your server
- Screenshots through the system file picker on Android and the photo library on iOS
- signOut ends the session from your own sign out

Install

```
flutter pub add dbrij_resolve
```

Quick start

```
final resolve = ResolveClient(desk: 'rk_...', storage: MyStorage());Navigator.of(context).push(MaterialPageRoute(  builder: (ctx) => Scaffold(    body: SafeArea(      child: ResolveSupport(        desk: 'rk_...',        client: resolve,        identity: ResolveIdentity(email: user.email, externalId: user.id, userHash: user.resolveHash),        onClose: () => Navigator.of(ctx).pop(),      ),    ),  ),));
```

### glass.js

The Glass tracker for websites: page views, clicks, custom events and session replay from one script tag.

Script for your site · JavaScript · Served by Dbrij · Runs on Browsers

- Sends events in batches every 5 seconds or at 20 waiting, and once more when the page closes
- Follows route changes in single page apps through the history API
- Replay is recorded by a second file, fetched only for sessions the sample picks
- No cookies and no fingerprinting; Global Privacy Control turns off replay and identify
- glass.track and glass.identify for moments your code names
- Never breaks the page: every part is wrapped and fails silently

Install

```
<script src="https://glass.dbrij.com/glass.js" data-site="gk_your_site_key" defer></script>
```

Quick start

```
<script src="https://glass.dbrij.com/glass.js" data-site="gk_your_site_key" defer></script><script>  // once the tag has loaded  glass.track('signup', { plan: 'pro' });  glass.identify('user_1234', { plan: 'pro' });</script>
```

### @dbrij/glass-native

Glass analytics for React Native: sessions, screens, taps and events in the same dashboard as your website.

SDK · TypeScript · npm · Runs on React Native, Any runtime with fetch

- screen, track, identify and tap, with hooks for the app going to the foreground or background
- Batches 20 events or every 5 seconds, and flushes when the app goes to the background
- An offline queue of up to 500 events, sent on the next launch
- Stops sending when the monthly quota is used up or the site is paused
- No cookies, no fingerprinting and no replay; setDisabled stops and clears everything
- Never throws into your app

Install

```
npm install @dbrij/glass-native
```

Quick start

```
import AsyncStorage from '@react-native-async-storage/async-storage';import { AppState, Dimensions, Platform } from 'react-native';import { createGlass } from '@dbrij/glass-native';export const glass = createGlass({  siteKey: 'gk_your_site_key',  platform: { os: Platform.OS === 'ios' ? 'ios' : 'android', device: 'mobile', appVersion: '1.4.2' },  storage: AsyncStorage,  screen: Dimensions.get('screen'),});AppState.addEventListener('change', (state) => {  if (state === 'active') glass.onForeground();  else if (state === 'background') glass.onBackground();});glass.track('signup', { plan: 'pro' });
```

### glass-tracker.swift

The Glass tracker for native iOS apps, as one Swift file you drop into your project.

SDK · Swift · Served by Dbrij · Runs on iOS, Other Swift platforms with Foundation

- One file with no dependencies beyond Foundation
- On iOS it follows the app lifecycle for you: flushes on background, refreshes on foreground
- screen, track, identify and tap, the same calls as every Glass tracker
- A random visitor id in UserDefaults; no advertising id and no fingerprinting
- Batches of 20 or every 5 seconds, with a queue that survives being offline

Install

```
curl -O https://dbrij.com/glass-tracker.swift
```

Quick start

```
let glass = GlassTracker(siteKey: "gk_your_site_key", appVersion: "1.4.2")glass.screen("Checkout")glass.track("signup", props: ["plan": "pro"])glass.identify("user_1234", traits: ["plan": "pro"])glass.tap(xPct: 48, yPct: 88, label: "buy-button")
```

### GlassTracker.kt

The Glass tracker for native Android apps, as one Kotlin file you drop into your project.

SDK · Kotlin · Served by Dbrij · Runs on Android

- One file using only the Android SDK
- Built with an Application, it follows the activity lifecycle for you
- screen, track, identify and tap, the same calls as every Glass tracker
- All work on one background thread, and nothing ever throws into your app
- A random visitor id in SharedPreferences; no advertising id and no fingerprinting

Install

```
curl -O https://dbrij.com/GlassTracker.kt
```

Quick start

```
val glass = GlassTracker(application, GlassTracker.Config(    siteKey = "gk_your_site_key",    appVersion = "1.4.2",))glass.screen("Checkout")glass.track("signup", mapOf("plan" to "pro"))glass.identify("user_1234", mapOf("plan" to "pro"))glass.tap(48.0, 88.0, "buy-button")
```

### glass_tracker.dart

The Glass tracker for Flutter apps, as one Dart file you drop into lib.

SDK · Dart · Served by Dbrij · Runs on Flutter, Dart with dart:io

- One file using only dart:io and dart:convert
- screen, track, identify and tap, the same calls as every Glass tracker
- Wire the lifecycle with a WidgetsBindingObserver and screens with a NavigatorObserver
- Memory by default; back GlassStorage with shared preferences to keep the queue across launches

Install

```
curl -O https://dbrij.com/glass_tracker.dart
```

Quick start

```
final glass = GlassTracker(GlassConfig(  siteKey: 'gk_your_site_key',  platformOs: Platform.isIOS ? 'ios' : 'android',  appVersion: '1.4.2',));glass.screen('Checkout');glass.track('signup', {'plan': 'pro'});glass.identify('user_1234', {'plan': 'pro'});
```

### @dbrij/search

Dbrij Search in the browser: a typed client, click and conversion tracking, a headless controller, ready made widgets and React components.

SDK · TypeScript · npm · Runs on Browsers, React 17+ for the components

- SearchClient for search, suggestions, answers and recommendations
- Clicks and conversions attributed to the search that produced them
- mountSearch and mountAutocomplete widgets, styled with CSS variables
- Unstyled React components from @dbrij/search/react
- createSearch, the headless controller under the widgets and components
- Anonymous user tokens that join a profile when the person signs in

Install

```
npm install @dbrij/search
```

Quick start

```
import { SearchClient } from '@dbrij/search';const client = new SearchClient({ key: 'dbrij_live_your_search_key' });const results = await client.search('products', { q: 'running shoes', facets: ['brand'] });client.insights.clickedAfterSearch({ index: 'products', queryId: results.queryId, objectIds: ['sku-1'], positions: [3] });
```

### search.js

Search on any website with one script tag: box, refinements, results and pages, or a panel that opens from your own search box.

Script for your site · JavaScript · Served by Dbrij · Runs on Browsers

- Draws the whole search inside an element, starting from the query in the page address
- Or opens a panel over the page from your own input, and from the slash key anywhere
- Refinements, a fixed filter, answers and plain language filters, all set on the tag
- Built from the npm package source, so the two never drift apart
- Everything is on window.DbrijSearch for anything custom

Install

```
<script src="https://search.dbrij.com/search.js" async  data-key="dbrij_live_your_search_key"  data-index="products"  data-target="#search"></script>
```

Quick start

```
<div id="search"></div><script src="https://search.dbrij.com/search.js" async  data-key="dbrij_live_your_search_key"  data-index="products"  data-target="#search"  data-facets="brand,category"></script>
```

### @dbrij/storage

Buckets, uploads, delivery links and image transformations from Node or the browser.

SDK · TypeScript · npm · Runs on Node 18+, Browsers

- buckets.list and buckets.create
- objects.upload gets a presigned address, sends the bytes straight to the store and confirms them
- delivery.url makes permanent links for public objects and signed, expiring ones for private
- transform builds resize, crop, format and quality options for images
- presetUpload lets a browser upload through a preset with no key
- Zero dependencies

Install

```
npm install @dbrij/storage
```

Quick start

```
import { DbrijStorage, transform } from '@dbrij/storage';const storage = new DbrijStorage({ keyId: process.env.DBRIJ_KEY_ID!, secret: process.env.DBRIJ_KEY_SECRET! });const bucket = await storage.buckets.create('my-assets');await storage.objects.upload(bucket.id, 'images/logo.png', bytes, { contentType: 'image/png' });const link = await storage.delivery.url(bucket.id, 'images/logo.png', { transform: transform({ width: 800, format: 'auto' }) });
```

### storage-widget.js

An upload window for any web page: people pick files and they land in your bucket through an upload preset, with no key in the page.

Script for your site · JavaScript · Served by Dbrij · Runs on Browsers

- DbrijStorage.open shows a drop zone with progress for each file
- DbrijStorage.attach turns your own button into an upload button
- The preset sets the folder, the accepted types, the size limit and the origins allowed
- Bytes go straight to the store through a presigned address, then each file is confirmed

Install

```
<script src="https://storage.dbrij.com/storage-widget.js"></script>
```

Quick start

```
<script src="https://storage.dbrij.com/storage-widget.js"></script><script>  DbrijStorage.attach(document.querySelector('#upload'), {    preset: 'dbup_…',    onUploaded: (file) => console.log(file.deliveryUrl),  });</script>
```

### forms-embed.js

Put a Dbrij form on any website with one script tag, as a button that opens it or inline in the page.

Script for your site · JavaScript · Served by Dbrij · Runs on Browsers

- A button that opens the form over the page in a centred window
- Inline mode puts the form in the page and grows it to fit
- Button words and colour are set on the tag
- The form loads only when somebody asks for it
- No globals and inline styles only; several forms on one page each work on their own

Install

```
<script src="https://app.dbrij.com/forms-embed.js" data-form="job-application" data-label="Apply now" async></script>
```

Quick start

```
<script src="https://app.dbrij.com/forms-embed.js" data-form="job-application" data-mode="inline" data-height="720" async></script>
```

### reach-form.js

A floating contact button for any website that opens a Dbrij form in a panel.

Script for your site · JavaScript · Served by Dbrij · Runs on Browsers

- A round button in the corner opens the hosted form in a panel over the page
- Stacks above the Resolve support bubble when both share a corner
- Steps aside while the support chat is open
- Loads the form only when a visitor opens it; Escape closes it

Install

```
<script src="https://dbrij.com/reach-form.js" data-form="YOUR_FORM_SLUG" data-origin="https://dbrij.com" defer></script>
```

Quick start

```
<!-- before </body> --><script src="https://dbrij.com/reach-form.js" data-form="YOUR_FORM_SLUG" data-origin="https://dbrij.com" defer></script>
```

### proof-capture.js

A Report a bug button for your own web app that files each report, with the errors the page hit, into your company's bug triage.

Script for your site · JavaScript · Served by Dbrij · Runs on Browsers

- Keeps the last console errors and failed requests from the moment it loads
- Never sends a request or response body, nor a query string
- Reports carry the page, the browser, an optional screenshot and the Glass visit when Glass runs
- window.dbrijBugs.open and report for your own button or form
- Draws its form in a shadow root, so your styles and its styles never mix

Install

```
<script src="https://dbrij.com/proof-capture.js" data-key="pc_..." async></script>
```

Quick start

```
<script src="https://dbrij.com/proof-capture.js" data-key="pc_..." data-build="2.4.1" data-button="off" async></script><script>  document.querySelector('#report').onclick = () => window.dbrijBugs.open();</script>
```

### dbrij

The Dbrij command line: deploy to Hosting from any directory, run your app with its Dbrij Secrets, and cut Ship releases from your CI.

Command line · TypeScript · npm · Runs on Node 20+

- dbrij deploy packs this directory and ships it, with no repository connection or webhook
- Sign in once with a code you confirm in your browser, or set DBRIJ_TOKEN in your CI
- Leaves out node_modules, .env files and keys, and follows .gitignore and .dbrijignore
- dbrij secrets run starts your command with its secrets opened on this machine
- dbrij ship uploads bundles and asset packs and moves rollouts
- dbrij mcp lets an AI coding assistant deploy for you, while anything costly stays a request you approve

Install

```
npm i -g dbrij
```

Quick start

```
npm i -g dbrijdbrij login      # confirm the code in your browserdbrij link       # point this directory at a servicedbrij deploy     # ship it
```

### dbrij-sdk.js

A single file JavaScript client for the Developer API: meetings, calls, chat, media uploads and realtime tokens.

SDK · JavaScript · Served by Dbrij · Runs on Node 18+, Browsers

- Meetings: create, list, end, record, and mint join tokens for your own users
- Calls inside a conversation that ring its members
- Conversations and messages: send, react, edit, delete, mark read and read receipts
- Signed media uploads, with a browser helper that returns an attachment
- Unwraps every response and throws DbrijError with the status

Install

```
curl -O https://dbrij.com/dbrij-sdk.js
```

Quick start

```
import { DbrijClient } from './dbrij-sdk.js';const dbrij = new DbrijClient({ apiKey: process.env.DBRIJ_API_KEY });const meeting = await dbrij.createMeeting({ title: 'Demo', host: { externalUserId: 'user_1' } });const { url, token } = await dbrij.mintToken(meeting.id, { externalUserId: 'user_2' });
```
