Skip to main content

Variable Scope System

The Nuraly micro-app architecture implements a two-tier variable scope system that provides flexible state management across different levels of isolation and sharing.

Overview

Variables in micro-apps can exist at two different scope levels:

ScopeStorage LevelSharing BehaviorUse Cases
LOCALPer micro-app instanceIsolated - each instance has its own storageTemporary UI state, form inputs, component-specific data
GLOBALSingleton across all appsShared across ALL instances regardless of appAuthentication status, theme, language settings

Architecture Overview

Key Points
  • LOCAL Scope: Isolated per instance, cleared on unmount, default for all variables
  • GLOBAL Scope: Shared across ALL instances, persists for session, triggers global events
  • Singleton Pattern: One SharedVariableRegistry instance for entire application

Scope Resolution Flow

When you access a variable without an explicit scope prefix, the system automatically resolves it:

Resolution Order: LOCALGLOBALundefined


Variable Access Patterns

Setting LOCAL Variables

// Implicit - defaults to LOCAL
Vars.clickCount = 5
Vars.tempData = { foo: 'bar' }

// Explicit
Vars['local.formData'] = { name: '', email: '' }

Setting GLOBAL Variables

// Must use explicit prefix
Vars['global.theme'] = 'dark'
Vars['global.userName'] = 'John Doe'
Vars['global.isAuthenticated'] = true

Getting Variables

// Auto-resolution (searches LOCAL → GLOBAL)
const userName = Vars.userName

// Explicit scope access
const theme = Vars['global.theme'] // Only checks GLOBAL
const temp = Vars['local.tempData'] // Only checks LOCAL

Complete Access Pattern Flow


Global Variable Event Propagation

When a GLOBAL variable changes, the event propagates to all micro-app instances:


Variable Lifecycle


Class Structure


Runtime Deployment

This diagram shows how the system works in practice with real applications:


API Reference

Publishing to Global Scope

You can promote a LOCAL variable to GLOBAL scope:

// Start with local variable
Vars.selectedProduct = { id: 123, name: 'Widget' }

// Publish to global scope
Runtime.publishToGlobal('selectedProduct')

// Now accessible globally
console.log(Vars['global.selectedProduct'])

Subscribing to Variable Changes

// Subscribe to variable changes
const unsubscribe = Runtime.subscribeToVar('global.theme', (newTheme) => {
console.log('Theme changed to:', newTheme)
updateUITheme(newTheme)
})

// Cleanup when done
unsubscribe()

Best Practices

Guidelines
  1. Use LOCAL by default - Keep variables private unless needed elsewhere
  2. Use GLOBAL sparingly - Only for truly global state (auth, theme, etc.)
  3. Explicit prefixes - Use global. prefix for clarity when setting globals
  4. Subscribe carefully - Always unsubscribe to prevent memory leaks
  5. Avoid large objects - GLOBAL variable changes trigger updates in ALL instances
  6. ⚠️ Not a security boundary - All micro-apps run in same JavaScript context

Performance Considerations

  • GLOBAL variables trigger updates in ALL instances - use judiciously
  • LOCAL variables are most performant - updates don't propagate
  • Smart Caching - Proxies cached using WeakMap for automatic garbage collection
  • Efficient Events - Only affected components refresh on variable changes

Common Patterns

Pattern 1: Component-Specific State

// Good - Uses LOCAL scope by default
Vars.isLoading = true
Vars.errorMessage = null
Vars.formData = { name: '', email: '' }

Pattern 2: Application-Wide State

// Good - Explicit GLOBAL for shared state
Vars['global.theme'] = 'dark'
Vars['global.userName'] = currentUser.name
Vars['global.isAuthenticated'] = true

Pattern 3: Conditional Publishing

// Start local, publish when needed
Vars.draftArticle = { title: '', content: '' }

// User clicks "Share with team"
Runtime.publishToGlobal('draftArticle')

Next Steps

  • Learn about Micro-App Architecture
  • Explore Component Communication (coming soon)
  • See Handler Execution (coming soon)