Docs / Contact / sdks/javascript/getting-started
JavaScript SDK: Getting Started
Go from zero to publishing data in under a minute. The SDK uses the native fetch API with zero external dependencies and includes React hooks for instant component integration.
Requirements: Node.js 16+ or modern browser (Chrome 88+, Firefox 84+, Safari 14+, Edge 88+)
Install
The SDK installs straight from GitHub:
npm install github:tendrl-inc-labs/js-sdk
It installs under its package name tendrl — the imports below work unchanged. (The SDK is plain JavaScript with no build step, so the GitHub install ships exactly what a registry install would.)
Every client needs an entity API key. If you haven't created one yet, create your first entity and copy its API key from the Connection Instructions dialog.
Your First Message (4 Lines)
const client = new TendrlClient({ apiKey: 'your_api_key' });
client.start();
client.publish({ temperature: 23.5, humidity: 60 }, ['sensor']);
The message is queued, batched, and delivered. Tags route it to your flows and connectors.
Pointing at a different server
By default the client talks to https://app.tendrl.com. Set TENDRL_APP_URL to point it at a local development stack instead:
TENDRL_APP_URL=http://localhost:8000 node app.js
It accepts either a bare origin (http://localhost:8000) or a full base URL ending in /api, so the same variable works for the Python, Go, and nano-agent clients too. In a browser, where there is no process.env, pass apiBaseUrl to the constructor instead.
React: One Hook, Full Integration
The useTendrlClient hook gives you a connected client, reactive status, and publish/receive functions, all managed automatically with the component lifecycle:
function SensorDashboard() {
const { isConnected, publish } = useTendrlClient({
onMessage: (msg) => console.log('Command:', msg.data),
offlineStorage: true
});
return (
<div>
<p>Status: {isConnected ? 'Online' : 'Offline'}</p>
<button onClick={() => publish({ temperature: 23.5 }, ['sensor'])}>
Send Reading
</button>
);
}
The hook starts the client on mount, stops it on unmount, and isConnected updates reactively. No cleanup code to write.
Set your API key as an environment variable and skip the config entirely:
REACT_APP_TENDRL_KEY=your_api_key
Route Inbound Messages
Handle messages sent back from Contact flows. Route by tag with client.on():
client.on({ tag: 'diagnostic' }, (message) => {
client.publish(selfTest(), ['diagnostic-result']);
});
client.on({ tag: 'ai-response' }, (message) => {
console.log('AI:', message.data?.response);
});
client.on({ tags: ['alert', 'anomaly'] }, (message) => {
console.log('Alert:', message.data);
});
client.setMessageCheckRate(3000);
setMessageCallback remains available as a catch-all fallback for unmatched messages.
Track Device State
Every entity has a persistent state table, a key-value store accessible from the dashboard and other entities:
// Merge new data (existing keys preserved)
await client.updateState({
firmware: '2.1.0',
status: 'active'
});
// Read it back
const state = await client.getState();
// Trigger a flow when state changes
await client.updateState(
{ status: 'maintenance' },
['status-change']
);
Receive remote state changes with onState(), which is polled at the same interval as messages:
client.onState((state) => {
if (state.status === 'needs_maintenance') {
runDiagnostics();
}
});
Offline Storage with Zero Configuration
Enable IndexedDB persistence with one flag. Messages queue locally when the network drops and send automatically when it returns:
const client = new TendrlClient({
apiKey: 'your_key',
offlineStorage: true
});
No retry logic to write. No local database to manage. The SDK handles storage, TTL expiration, and batch replay.
What You Get for Free
When you call client.start(), the SDK automatically:
- Batches messages: groups publishes into efficient bulk sends
- Adapts to load: batch size scales with queue depth
- Monitors connectivity: detects network changes and updates entity status
- Stores offline messages: IndexedDB persistence with automatic retry
- Cleans up expired data: TTL-based cleanup every 60 seconds
Complete Example
const client = new TendrlClient({
apiKey: 'your_api_key',
offlineStorage: true
});
client.on({ tag: 'ai-response' }, (msg) => {
console.log(`[${msg.msg_type}] ${JSON.stringify(msg.data)}`);
return true;
});
client.setMessageCheckRate(5000);
client.start();
// Publish sensor data every 10 seconds
setInterval(() => {
client.publish(
{ temperature: 23.5, humidity: 60 },
['sensor', 'environment']
);
}, 10000);
What's Next
- Configuration: All config options and tuning
- Examples: React dashboards, Node.js services, and more
- API Reference: Full method documentation
Tendrl