The Infinite Interface
"The SDK isn't a library. It's a lens. It lets your frontend see your backend as a set of infinite local powers."
The "Library-First" Myth
"What if your backend wasn't across the network, but right there in your browser? What if the network was just a transparent pipe? That is the Chainbox reality."
The Big Picture
When you trigger a backend call from the browser, Chainbox handles the heavy lifting automatically:
Full "Hello World" Tutorial
Let's build a simple "Add Numbers" feature from scratch using the CDN library.
1. Define the Backend (Capability)
Create a file at src/_chain/Math.Add.ts. This is pure backend code.
export default async function Add(ctx, input) {
// input.a and input.b come from the browser
return input.a + input.b;
}
2. Create the HTML Page
No build tools required. Just plain HTML.
<!DOCTYPE html>
<html>
<head>
<!-- Configure the library -->
<meta name="chainbox:url" content="http://localhost:4000/execute">
<script src="https://unpkg.com/@sddion/chainbox/dist/chainbox.min.js"></script>
</head>
<body>
<!-- The magic button -->
<button
cb-call="Math.Add"
cb-input='{"a": 10, "b": 20}'
cb-on-success="showResult">
Calculate
</button>
<div id="output"></div>
<script>
function showResult(sum) {
document.getElementById('output').innerText = "The sum is: " + sum;
}
</script>
</body>
</html>
Isomorphic Design
The SDK automatically adapts its transport mechanism based on the execution environment:
Server-Side
Uses Local transport to execute functions directly in-process for maximum speed and zero network latency.
Client-Side
Uses Http transport to POST requests to the backend securely.
Key Dependencies
The Client SDK relies on a minimal set of high-performance libraries:
-
@supabase/supabase-jsPrimary Database & Auth Used as the primary provider for database interactions and authentication state management. -
undiciHigh-performance HTTP Used for the Mesh transport layer to ensure fast and reliable network requests. -
jitiRuntime Compilation Handles runtime TypeScript compilation to load user functions dynamically without a build step. -
joseJWT Handling Provides secure JSON Web Token signing, verification, and management.
Zero-Config (CDN)
For plain HTML/CSS projects, use the lightweight CDN bundle (dist/chainbox.min.js). It features zero-config auto-discovery and professional-grade security.
<!-- Auto-configure via meta tags -->
<meta name="chainbox:url" content="https://api.yourproject.com/execute">
<script src="https://cdn.yourproject.com/chainbox.min.js"></script>
Scoped Environment Variables
Chainbox automatically fetches .env files from your server and syncs them to both
JavaScript (Chainbox.env.get()) and CSS (--cb-env-*).
Security Enforcement:
By default, **only** variables starting with
PUBLIC_ are exposed to the browser. This prevents your database keys or private
secrets from leaking to users.
PUBLIC_SITE_NAME="My Project"
STRIPE_SECRET_KEY="sk_test..."
Attribute-Driven Calls
Chainbox allows you to trigger backend logic directly from your HTML elements. This is the fastest way to build interactive features.
<button
cb-call="User.Update"
cb-input="#profile-form"
cb-on-success="notify">
Save Profile
</button>
| Attribute | Description | |
|---|---|---|
| cb-call | Required. | The name of the backend function to run. |
| cb-input | Optional. | Can be a CSS selector (like
#my-form) or raw JSON data.
|
| cb-on-success | Optional. | The name of a JavaScript function to run after success. |
Chainbox Inspector
In development mode (localhost) or when enabled via CHAINBOX_INSPECTOR=true, a floating
visual overlay allows you to inspect the logical trace of every backend call in real-time.
Click the "C" bubble in the corner to see exactly what happened under the hood. It's like having "X-Ray vision" for your backend.
JavaScript API Reference
If you prefer writing code over attributes, use the global Chainbox object.
Chainbox.Call(name, input)
Triggers a backend capability and returns the result.
const result = await Chainbox.Call("Sum", { a: 1, b: 2 });
console.log(result); // 3
Chainbox.env.get(key)
Gets a public environment variable.
const name = Chainbox.env.get("PUBLIC_APP_NAME");
Lifecycle Events
Listen to results globally or on specific elements.
document.addEventListener('cb-success', (e) => {
const { detail } = e;
alert("Execution finished: " + JSON.stringify(detail));
});