Configuration
Complete reference for telemetry.config.json
Configuration
Complete reference for telemetry.config.json.
Overview
Every TelemetryOS application must include a telemetry.config.json file at the root of the project. This file defines the application's metadata, mount points, workers, containers, and development settings.
Required Fields
{
"name": "my-application",
"version": "1.0.0",
"mountPoints": {
"render": "/render"
}
}name
Type: string (required)
Unique identifier for the application. Used by the platform for builds, deployment, and Studio registration.
{
"name": "weather-widget"
}Use lowercase names with hyphens. No spaces or special characters are allowed. The name must be unique within your account and cannot be changed after deployment.
version
Type: string (required)
Application version. The tos CLI uses CalVer format by default.
{
"version": "2026.4.0"
}The CalVer format is YYYY.M.PATCH, where YYYY is the year, M is the month, and PATCH increments with each release. SemVer (MAJOR.MINOR.PATCH) is also accepted.
mountPoints
Type: object (required)
Defines the URL paths for application components. At minimum, must include render.
{
"mountPoints": {
"render": "/render",
"settings": "/settings"
}
}Mount point values can be strings or objects with a path property:
{
"mountPoints": {
"render": "/render",
"settings": { "path": "/settings" }
}
}Standard Mount Points:
| Mount Point | Required | Description |
|---|---|---|
render | Yes | Content displayed on devices |
settings | No | Configuration UI in admin portal sidebar |
web | No | Browser-accessible management interface (via URL in any browser) |
All paths must start with / and can be any valid URL path. The conventional paths are /render and /settings. The web path must match the application name (e.g., "web": "/my-app" for an app named my-app).
Optional Fields
description
Type: string (optional)
Description of the application shown in Studio.
{
"description": "Display weather forecasts for configured cities"
}useSpaRouting
Type: boolean (optional, default: false)
Enables client-side SPA routing for the application. Required when using the web mount point, which relies on React Router for multi-level navigation.
{
"useSpaRouting": true
}When enabled, the platform routes all sub-paths back to the application so that React Router handles navigation client-side. Without it, page refreshes or direct navigation to sub-routes (e.g., /queue-manager/l/Downtown) return a 404.
backgroundWorkers
Type: object (optional)
Background scripts that run continuously on devices and as Web Workers in the admin portal, even when the application isn't visible.
{
"backgroundWorkers": {
"sync": "workers/sync.js",
"monitor": { "path": "workers/monitor.js" }
}
}Each key is the worker name, and the value is either a path string or an object with a path property pointing to the built worker file. Workers run independently in their own context with full SDK access and shared storage.
Use the @telemetryos/vite-plugin-application-workers Vite plugin to bundle workers as part of the build.
serverWorkers
Type: object (optional)
Server-side scripts that run as Cloudflare Workers on the edge, providing serverless API endpoints and backend functionality.
{
"serverWorkers": {
"api": "workers/api.js",
"webhook": { "path": "workers/webhook.js" }
}
}Each key is the worker name, and the value is either a path string or an object with a path property. Server workers use the Cloudflare Workers runtime (ESM format), not a browser JavaScript environment.
containers
Type: object (optional)
Docker containers to run alongside the application on devices.
{
"containers": {
"api-server": { "image": "myapp/backend:latest", "port": 3000 },
"redis": { "image": "redis:7-alpine", "port": 6379 }
}
}Each key is the container name (lowercase, no spaces), which becomes its hostname on the device (e.g., accessible at http://api-server). The value is an object with the container configuration:
| Field | Type | Description |
|---|---|---|
image | string | Docker image name and tag |
port | number | Internal port container listens on |
Containers only run on physical devices, not in the admin portal. Images must be publicly accessible or pre-loaded on the device.
logoPath
Type: string (optional)
Path to the application's logo image, displayed in the development host UI.
{
"logoPath": "public/assets/logo.svg"
}thumbnailPath
Type: string (optional)
Path to a thumbnail image for the application, displayed in the Developer App and Studio.
{
"thumbnailPath": "public/assets/thumbnail.png"
}devServer
Type: object (optional but recommended)
Configuration for local development with tos dev.
{
"devServer": {
"runCommand": "vite --port $PORT",
"url": "http://localhost:$PORT",
"readyPattern": "VITE.*ready in"
}
}devServer Object:
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | URL where dev server will be accessible |
runCommand | string | No | Command to start local dev server |
readyPattern | string | No | Regex pattern to detect server readiness from stdout |
$PORT variable: Use $PORT in runCommand and url instead of hardcoding a port number. The Developer App auto-assigns an available port and replaces $PORT at runtime, avoiding port conflicts when multiple projects are open.
If readyPattern is provided, the Developer App watches the dev server's stdout for a match to determine when the server is ready. If omitted, it polls the url instead.
Common Commands:
// Vite
"runCommand": "vite --port $PORT"
// Webpack Dev Server
"runCommand": "webpack serve --port $PORT"
// Next.js
"runCommand": "next dev --port $PORT"Complete Example
{
"name": "restaurant-menu-board",
"version": "2026.4.0",
"description": "Dynamic digital menu board with real-time price updates and promotional content",
"useSpaRouting": true,
"logoPath": "public/assets/logo.svg",
"thumbnailPath": "public/assets/thumbnail.png",
"mountPoints": {
"render": "/render",
"settings": "/settings",
"web": "/restaurant-menu-board"
},
"backgroundWorkers": {
"price-sync": "workers/price-sync.js",
"inventory-monitor": "workers/inventory-monitor.js"
},
"serverWorkers": {
"api": "workers/api.js"
},
"containers": {
"menu-api": { "image": "restaurant/menu-api:v2.1.0", "port": 3000 },
"redis-cache": { "image": "redis:7-alpine", "port": 6379 }
},
"devServer": {
"runCommand": "vite --port $PORT",
"url": "http://localhost:$PORT",
"readyPattern": "VITE.*ready in"
}
}Minimal Example
{
"name": "simple-clock",
"version": "1.0.0",
"mountPoints": {
"render": "/render"
}
}Validation
The TelemetryOS platform validates the configuration on upload.
The platform checks that the name field exists and is valid, that the version field exists, that mountPoints.render is defined, that all mount point paths start with /, that background and server worker paths are relative, and that container names are valid hostnames.
The platform also issues warnings for common oversights: a missing settings mount point means the app will not be configurable by admins, a web mount point without useSpaRouting may cause client-side routing to break, container images may not be accessible from the device, and worker files that are not found will be flagged at build time.
Best Practices
Versioning
// Good - semantic versioning
"version": "1.0.0"
"version": "2.1.3"
// Bad - non-standard formats
"version": "v1.0"
"version": "latest"
"version": "1.0"Naming
// Good - lowercase with hyphens
"name": "weather-widget"
"name": "inventory-dashboard"
// Bad - spaces, uppercase, special chars
"name": "Weather Widget"
"name": "inventory_dashboard"
"name": "My App!"Mount Points
// Standard convention
"mountPoints": {
"render": "/render",
"settings": "/settings"
}
// With web mount point
"mountPoints": {
"render": "/render",
"settings": "/settings",
"web": "/my-app"
}
// Minimal (render only)
"mountPoints": {
"render": "/render"
}
// Valid but non-standard paths
"mountPoints": {
"render": "/",
"settings": "/config"
}Container Keys
// Good - valid hostnames
"containers": {
"api-server": { "image": "myapp/api:latest", "port": 3000 },
"redis": { "image": "redis:7-alpine", "port": 6379 }
}
// Bad - not valid hostnames
"containers": {
"API_Server": { "image": "myapp/api:latest", "port": 3000 },
"my cache": { "image": "redis:7-alpine", "port": 6379 }
}Environment-Specific Config
The config file itself doesn't support environment variables, but the build process can:
package.json:
{
"scripts": {
"build:dev": "vite build --mode development",
"build:prod": "vite build --mode production"
}
}Use environment variables in application code:
const API_URL = import.meta.env.VITE_API_URL;Deployment Workflow
- Build -
npm run buildcreates production files - Config Included -
telemetry.config.jsonmust be in build output - Platform Reads - TelemetryOS reads config on application upload
- Validation - Platform validates schema and requirements
- Deploy - Application becomes available for use
Common Issues
SDK Not Configured
Call configure() before using any SDK methods:
import { configure } from '@telemetryos/sdk';
configure();Missing Render Mount Point
// ❌ Invalid - no render
{
"name": "my-app",
"version": "1.0.0",
"mountPoints": {
"settings": "/settings"
}
}
// ✅ Valid - has render
{
"name": "my-app",
"version": "1.0.0",
"mountPoints": {
"render": "/render",
"settings": "/settings"
}
}Invalid Version Format
// ❌ Invalid
"version": "v1.0"
"version": "1"
"version": "1.0"
// ✅ Valid
"version": "1.0.0"
"version": "1.0.1"
"version": "2.1.3"Schema Reference
interface TelemetryConfig {
name: string;
version: string;
description?: string;
logoPath?: string;
thumbnailPath?: string;
useSpaRouting?: boolean;
mountPoints: {
render: string | { path: string };
settings?: string | { path: string };
web?: string | { path: string };
[key: string]: string | { path: string } | undefined;
};
backgroundWorkers?: Record<string, string | { path: string }>;
serverWorkers?: Record<string, string | { path: string }>;
containers?: Record<string, { image: string; port?: number }>;
devServer?: {
runCommand?: string;
url: string;
readyPattern?: string;
};
}Next Steps
- Mount Points - Understand render, settings, workers, containers
- Quick Start - Application creation guide
- Local Development - Use
tos devfor development
Updated 1 day ago