C
CanxJS
v1.6.2
  • Learn
  • Blog
  • Showcase
C
CanxJS

Ultra-fast async MVC backend framework for Bun. Build production-ready APIs with elegance and speed.

Resources

  • Documentation
  • Learn
  • Blog
  • Showcase

Documentation

  • Introduction
  • Installation
  • Core Concepts
  • CLI Commands
  • API Reference

Legal

  • Privacy Policy
  • Terms of Service

© 2026 CanxJS. All rights reserved.

Built with ❤️ for Candra Kirana

  • Cluster Mode
  • Microservices
  • Observability
  • Security Layers
  • Universal Signals
  • Canx Flow
  • Maintenance
Enterprise

Universal Signals

Revolutionary "Zero-API" architecture for real-time state synchronization. Change a value on the server, and the UI updates instantly across all clients.

Zero-API Design

No REST endpoints needed. Just set a value on the server, UI updates instantly.

Real-time Sync

Changes propagate to all connected clients via WebSocket in milliseconds.

State Persistence

Optionally persist signal values to database for recovery after restart.

Cluster Support

Signals sync across all server instances via Redis pub/sub.

How It Works

CanxJS uses Redis Pub/Sub to sync signals across the cluster. Set cluster: true and you're done.

  • 1.Across your entire server cluster via Redis pub/sub
  • 2.To all connected frontend clients via WebSocket
  • 3.Optionally persisted to the database for recovery

Creating Signals (Backend)

Use useSignal() to create a reactive variable. Configure sync options based on your needs.

services/stats.ts
1import { useSignal } from 'canxjs';
2
3// Define a signal with options
4const onlineUsers = useSignal('stats:online', 0, {
5 syncToClient: true, // Broadcast to all connected frontends
6 persistence: true, // Persist to database
7 cluster: true // Sync across all server instances
8});
9
10// Update value from anywhere in your code
11async function userConnected() {
12 await onlineUsers.set(onlineUsers.value + 1);
13 // Automatically syncs to Redis cluster + all WebSocket clients
14}
15
16async function userDisconnected() {
17 await onlineUsers.set(onlineUsers.value - 1);
18}

Consuming Signals (Frontend)

Import from canxjs/client and use the same useSignal() hook. It auto-subscribes via WebSocket.

components/Dashboard.tsx
1// Client-side code (React/Next.js)
2import { useSignal } from 'canxjs/client';
3
4export function StatsWidget() {
5 // Auto-subscribes via WebSocket
6 const users = useSignal('stats:online');
7
8 return (
9 <div className="stats-card">
10 <span className="count">{users}</span>
11 <span className="label">Online Users</span>
12 </div>
13 );
14}
15
16// Multiple signals
17export function Dashboard() {
18 const online = useSignal('stats:online');
19 const orders = useSignal('stats:orders_today');
20 const revenue = useSignal('stats:revenue');
21
22 return (
23 <div className="dashboard">
24 <Stat label="Online" value={online} />
25 <Stat label="Orders" value={orders} />
26 <Stat label="Revenue" value={`$${revenue}`} />
27 </div>
28 );
29}

Advanced Patterns

Signals support complex data, computed values, and auto-refresh intervals.

services/dashboard.ts
1// Signals with complex data
2const cartSignal = useSignal('cart:user-123', { items: [], total: 0 });
3
4// Update nested data
5await cartSignal.set({
6 ...cartSignal.value,
7 items: [...cartSignal.value.items, newItem],
8 total: cartSignal.value.total + newItem.price
9});
10
11// Signal with computed values
12const statsSignal = useSignal('dashboard:stats', null, {
13 compute: async () => ({
14 users: await User.count(),
15 orders: await Order.countToday(),
16 revenue: await Order.sumRevenue()
17 }),
18 refreshInterval: 5000 // Recompute every 5 seconds
19});

Signal Options

OptionTypeDescription
syncToClientbooleanBroadcast changes to WebSocket clients
persistencebooleanPersist to database
clusterbooleanSync across server instances via Redis
computefunctionCompute value from async function
refreshIntervalnumberAuto-recompute interval (ms)

Next Steps

Explore other enterprise features for building real-time applications.