Welcome to Tahdeeth Docs!

Tahdeeth is an enterprise-grade Over-the-Air update platform built for React Native. Deploy critical patches instantly — without app store delays or user disruption.


What is Tahdeeth?

Tahdeeth is a sovereign code-push solution designed for regulated industries. It runs on Saudi-hosted infrastructure and gives engineering teams full control over rollout speed, target audiences, and rollback.

It ships a lightweight client SDK and a powerful CLI — so you can push, monitor, and roll back updates without leaving your terminal.

Features

bolt

Instant Updates

Ship JS bundle patches without going through the app store review process.

verified_user

Signature Verification

Every bundle is cryptographically signed and verified before install.

undo

Auto Rollback

Bad update? Automatically roll back to the last stable bundle.

public

Multi-Environment

Separate staging and production keys with per-environment rollout control.

sync

Retry Mechanism

Built-in retry logic ensures reliable delivery on poor connections.

lock

Sovereign Infra

Runs on Saudi-hosted infrastructure. Your data never leaves the region.

Required prerequisites

PrerequisiteVersion
Expo SDK≥ 50
@tahdeeth/cliLatest

Next Steps

Installation

Install the Tahdeeth SDK and its required peer dependency into your Expo project.


Install packages

$yarn add @almawrid/react-native-tahdeeth
$yarn add react-native-blob-util

Dependencies

PackageRequiredPurpose
@almawrid/react-native-tahdeethYesCore OTA update SDK
react-native-blob-utilYesRequired for downloading update bundles
warningreact-native-blob-util is a native module. Run npx pod-install after installation on iOS.

Next Steps

Initialization

Initialize the Tahdeeth SDK with your API key, then configure your native entry points so the SDK can serve OTA bundles at runtime.


Initialize the SDK

Call Tahdeeth.init() at the top of your entry file, before any component renders:

TypeScript
import Tahdeeth from '@almawrid/react-native-tahdeeth';
Tahdeeth.init({
apiKey: 'YOUR_API_KEY',
});
infoGet your API key from the Tahdeeth Dashboard. Each environment (staging, production) has its own key.

Native Setup

Override getJSBundleFile() in your MainApplication.kt:

Kotlin
import com.tahdeeth.Tahdeeth
override fun getJSBundleFile(): String? {
return Tahdeeth.bundleJS(this@MainApplication)
}

Next Steps

Tahdeeth CLI

A command-line tool for managing Tahdeeth hot updates — build bundles, upload versions, and control app updates directly from your terminal.


Installation

Terminal
npm install -g @almawrid/tahdeeth-cli
# or
yarn global add @almawrid/tahdeeth-cli

Quick Start

Four commands to go from zero to your first deployed update:

Terminal
# 1. Initialize config in your project root
tahdeeth-cli init
# 2. Log in to your Tahdeeth account
tahdeeth-cli login
# 3. Build the JS bundle
tahdeeth-cli build -p android
# 4. Upload the bundle
tahdeeth-cli upload -p android -v 1.0.1

Commands

terminaltahdeeth-cli initOne-time project setup

Creates a tahdeeth.json config file in the current directory. Run once per project before using any other commands. If the file already exists, the command exits without overwriting it.

Terminal
tahdeeth-cli init

You will be prompted for:

PromptDescriptionExample
Server URLBackend API base URLhttps://api.yourbackend.com
Dashboard URLDashboard web URLhttps://your.dashboard.com
Application IDYour app's unique ID in Tahdeethabc123

Generated tahdeeth.json:

json
{
"server_url": "https://api.yourbackend.com",
"dashboard_url": "https://your.dashboard.com",
"appId": "abc123"
}
terminaltahdeeth-cli loginAuthenticate with Tahdeeth

Opens the dashboard login page in your browser and waits for the OAuth flow to complete. The token is stored securely in the system keychain. Requires a valid tahdeeth.json. If already logged in, run logout first.

Terminal
tahdeeth-cli login
terminaltahdeeth-cli logoutRemove stored credentials

Removes your credentials from the system keychain.

Terminal
tahdeeth-cli logout
terminaltahdeeth-cli whoamiShow the logged-in user

Displays the currently authenticated user.

Terminal
tahdeeth-cli whoami
terminaltahdeeth-cli buildBuild a JS bundle for upload

Builds a React Native / Expo JS bundle and compresses it into a zip archive. The project type is auto-detected from package.json.

OptionAliasValuesDefault
--platform-pandroid · ios · bothboth
--type-tbundle · hermesbundle
Terminal
# Build for both platforms (default)
tahdeeth-cli build
# Android only
tahdeeth-cli build -p android
# iOS only
tahdeeth-cli build -p ios
# Hermes bytecode for Android
tahdeeth-cli build -p android -t hermes

Output files (inside bundles_outputs/):

PlatformTypeOutput file
Androidbundlebundles_outputs/android/index.android.bundle.zip
Androidbundlebundles_outputs/android/sourcemap.zip
iOSbundlebundles_outputs/ios/main.jsbundle.zip
iOSbundlebundles_outputs/ios/sourcemap.zip
terminaltahdeeth-cli uploadUpload a built bundle to your server

Uploads a built bundle to your Tahdeeth server. Must be logged in with a valid tahdeeth.json. Run build first.

OptionAliasValuesDefault
--platform-pandroid · ios · bothboth
--version-vstring1.0.0
Terminal
# Upload both platforms (default version)
tahdeeth-cli upload
# Android — tag version 1.2.0
tahdeeth-cli upload -p android -v 1.2.0
# iOS — tag version 2.0.0
tahdeeth-cli upload -p ios -v 2.0.0

Config File Reference

tahdeeth.json is created by init and read by login, build, and upload.

json
{
"server_url": "https://api.yourbackend.com",
"dashboard_url": "https://your.dashboard.com",
"appId": "your-app-id"
}
KeyDescription
server_urlBase URL of your Tahdeeth backend API
dashboard_urlBase URL of the dashboard (used for browser login)
appIdApplication identifier used when uploading bundles

Typical Workflow

Run init and login once per project. After that, every release is two commands.

Terminal
# Run once per project
tahdeeth-cli init
tahdeeth-cli login
# Each release
tahdeeth-cli build -p both -t bundle
tahdeeth-cli upload -p both -v 1.2.0

Next Steps

Configuration

Customize SDK behavior by passing options to Tahdeeth.init().


Options

OptionTypeRequiredDescription
apiKeystringYesEnvironment-specific API key from the dashboard
baseURLstringNoOverride the default server URL for self-hosted deployments

Example

TypeScript
Tahdeeth.init({
apiKey: "YOUR_API_KEY",
baseURL: "https://tahdeeth.cloider.com",
});
infobaseURL defaults to https://tahdeeth.cloider.com. Only override it if you are running a self-hosted instance.

Next Steps

Environments

Tahdeeth supports multiple deployment environments so you can safely test updates before rolling them out to production.


Overview

sciencestaging

Staging

Test your updates before they reach end users. Use a dedicated staging API key.

rocket_launchproduction

Production

Live environment. Updates pushed here are delivered immediately to all users.

How it works

  • key

    Each environment has its own API key. Pass the correct key to Tahdeeth.init() based on your build variant.

  • dashboard

    Environments are managed from the Tahdeeth Dashboard. You can create, rename, or revoke keys at any time.

  • shield

    Updates are scoped per environment — a bundle pushed to staging will never be served to a production build.

Next Steps

Usage

Integrate the Tahdeeth update flow into your root component. The SDK checks for updates on each app launch and installs them silently in the background.


Full Integration Example

TypeScript React
import React from "react";
import { View } from "react-native";
import BlobUtil from "react-native-blob-util";
import Tahdeeth from "@almawrid/react-native-tahdeeth";
import { useAsyncEffect } from "use-async-effect";
Tahdeeth.init({
apiKey: "YOUR_API_KEY",
baseURL: "https://tahdeeth.cloider.com",
});
export default function App() {
useAsyncEffect(async () => {
try {
const update = await Tahdeeth.fetchAvailableUpdate();
if (!update.updateAvailable) return;
const { bundleUrl, verified } =
await Tahdeeth.validateDownloadedUpdate(update);
if (!verified) return;
await Tahdeeth.downloadBundleUri(
BlobUtil,
bundleUrl,
update.version,
{ restartAfterInstall: true }
);
} catch (e) {
console.error("Tahdeeth Update Error:", e);
}
}, []);
return <View />;
}

Update Flow

01

Check for updates

Fetch available update metadata from the Tahdeeth server.

TypeScript
const update = await Tahdeeth.fetchAvailableUpdate();
02

Validate the bundle

Verify the cryptographic signature before downloading. Tampered or invalid bundles are rejected automatically.

TypeScript
const { bundleUrl, verified } =
await Tahdeeth.validateDownloadedUpdate(update);
03

Download and install

Download the bundle and restart the app to apply the update.

TypeScript
await Tahdeeth.downloadBundleUri(
BlobUtil, bundleUrl, update.version,
{ restartAfterInstall: true }
);

Next Steps

Security

Tahdeeth is built with security as a first-class concern. Every update bundle goes through a multi-layer verification process before it is applied to a device.


Signature Verification

verified_user

Cryptographic Signing

Every bundle is signed by the Tahdeeth server using asymmetric cryptography. The SDK verifies the signature on-device before applying any update.

block

Tamper Protection

If a bundle has been modified in transit, signature verification will fail and the update is discarded — keeping your users safe.

check_circle

Automatic Rejection

The SDK automatically rejects bundles that fail verification. No special error handling is required from your side.

What happens if verification fails?

The update is silently dropped. Your app continues running on the current bundle — no crash, no restart, no user impact. Failed verifications are logged to the Tahdeeth Dashboard for auditing.

health_and_safety

Safe by default

Tahdeeth follows a strict fail-safe model: if anything goes wrong during the update process — verification failure, download error, or network timeout — the app falls back to the last known-good bundle automatically.