How God’s Eye View Implements a No-Framework UI Using Direct DOM Manipulation

God’s Eye View builds its entire interface using native browser APIs like document.createElement and appendChild, deliberately avoiding React, Vue, or other heavyweight frameworks to minimize bundle size and maximize rendering performance.

God’s Eye View (GEV) is an open-source geospatial visualization tool that renders a 3-D globe using Cesium while maintaining a lightweight, interactive user interface. Unlike modern web applications that rely on virtual DOM diffing or component trees, GEV adopts a no-framework approach using direct DOM manipulation, hand-crafting every UI element with standard JavaScript. This architectural choice keeps the application bundle minimal and provides fine-grained control over rendering performance critical for real-time 3-D visualization.

Core Architecture of the No-Framework UI

The codebase organizes its interface logic into plain ES modules that export classes and helper functions, completely bypassing JSX or template compilers. These patterns enable GEV to function without any UI framework overhead.

Plain JavaScript Modules Without Virtual DOM

All UI code resides in standard ES modules (*.js) that contain no JSX transpilation or component lifecycle methods. In src/ui.js, the StyleManager class and various widget builders are implemented as plain JavaScript functions that instantiate DOM nodes directly. There is no virtual DOM abstraction or reactive dependency tracking—each module creates and returns actual HTMLElement objects that the browser renders immediately.

Native Element Creation with document.createElement

UI widgets such as buttons, panels, and sliders are instantiated using document.createElement and configured via direct property assignment. The entry point in src/main.js demonstrates this pattern by creating a credit container element:

// As implemented in src/main.js (line 106)
const creditEl = document.createElement('div');
creditEl.id = 'cesium-credits';
document.body.appendChild(creditEl);

This pattern recurs throughout the codebase. Complex widgets like the "POWER UP" chip are constructed by chaining createElement calls for container divs, buttons, and input elements, then appending them to form the component hierarchy.

Direct DOM Insertion via appendChild

Rather than delegating to a framework's renderer, GEV attaches elements to the document using appendChild or append methods. The src/annotations/screenAnnotationRenderer.js file shows this approach when building the SVG whiteboard overlay:

// Pattern from src/annotations/screenAnnotationRenderer.js (line 60)
const layer = document.createElement('div');
layer.className = 'gev-screen-whiteboard';
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('class', 'gev-screen-whiteboard-svg');
layer.appendChild(svg);
document.body.appendChild(layer);

These elements append directly to document.body or specific parent containers, bypassing any virtual DOM reconciliation process.

Manual Event Wiring with addEventListener

Interaction handling relies on standard addEventListener calls attached to created elements. The src/ui.js file contains multiple instances where UI widgets listen for clicks, keyboard events, and input changes directly:

// Typical pattern found in src/ui.js
const button = document.createElement('button');
button.textContent = 'POWER UP';
button.addEventListener('click', () => {
  // Open provider panel logic
});

This inline binding approach eliminates the need for synthetic event systems or delegated event handling frameworks, providing straightforward control over user interactions.

CSS-Driven Styling with Programmatic Control

Visual appearance is controlled primarily through external CSS files (src/ui.css, src/annotations.css), while JavaScript manages dynamic layout changes by toggling class names or updating CSS custom properties. The StyleManager class in src/ui.js (line 2187) exposes methods that update CSS custom properties for layout changes:

// From src/ui.js (line 2161)
updateLayout(width, height) {
  document.documentElement.style.setProperty('--gev-width', `${width}px`);
  document.documentElement.style.setProperty('--gev-height', `${height}px`);
}

This separation of concerns allows the JavaScript to focus on structural logic while CSS handles visual presentation.

Framework-Free State Management

Instead of Redux, MobX, or framework-specific stores, GEV uses plain JavaScript objects, Maps, and custom manager classes. The MapStackController and DataLayerManager expose simple methods like onChange and setStack that fire custom events when state mutates. In src/main.js (line 85), the map-stack controller fires custom events that UI components listen for directly:

// Concept from src/main.js (map-stack controller)
class MapStackController {
  setStack(newStack) {
    this.stack = newStack;
    window.dispatchEvent(new CustomEvent('stackchange', { detail: newStack }));
  }
}

UI components observe these events through standard addEventListener calls rather than reactive subscriptions.

Hybrid Rendering with Cesium

The application combines Cesium's WebGL-powered 3-D globe with DOM-based UI overlays that require no virtual DOM synchronization.

SVG Overlays and DOM Synchronization

While Cesium renders the heavy 3-D globe, annotation overlays use native DOM/SVG elements that are re-projected each frame. The screenAnnotationRenderer.js file constructs a <div> + <svg> overlay and updates its position in Cesium's postRender callback:

// Simplified from src/annotations/screenAnnotationRenderer.js (line 28)
function buildOverlay() {
  const overlay = document.createElement('div');
  overlay.className = 'screen-annotation-container';
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  overlay.appendChild(svg);
  return { overlay, svg };
}

Because these are real DOM nodes, the renderer updates their CSS transforms directly based on camera position, eliminating the overhead of virtual DOM diffing for high-frequency updates.

Practical Implementation Patterns

The following patterns demonstrate the create → configure → append → listen → update workflow used throughout GEV.

Creating UI Widgets

This example combines element creation, event binding, and CSS variable updates:

function makeControlPanel() {
  // Create container
  const panel = document.createElement('div');
  panel.className = 'gev-panel';
  
  // Add interactive button
  const button = document.createElement('button');
  button.textContent = 'POWER UP';
  button.addEventListener('click', () => alert('Open provider panel'));
  panel.appendChild(button);
  
  // Add brightness slider with direct CSS manipulation
  const slider = document.createElement('input');
  slider.type = 'range';
  slider.min = 0;
  slider.max = 100;
  slider.addEventListener('input', (e) => {
    document.documentElement.style.setProperty(
      '--gev-brightness', 
      `${e.target.value}%`
    );
  });
  panel.appendChild(slider);
  
  return panel;
}

document.body.appendChild(makeControlPanel());

Building SVG Annotation Layers

For geospatial annotations that overlay the 3-D view:

// Pattern from src/annotations/screenAnnotationRenderer.js
function createSvgOverlay() {
  const layer = document.createElement('div');
  layer.className = 'gev-screen-whiteboard';
  
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  svg.setAttribute('class', 'gev-screen-whiteboard-svg');
  svg.setAttribute('width', '100%');
  svg.setAttribute('height', '100%');
  
  layer.appendChild(svg);
  document.body.appendChild(layer);
  
  return { layer, svg };
}

Summary

God’s Eye View demonstrates that complex, interactive web applications can function without modern UI frameworks by adhering to these principles:

  • Direct DOM manipulation using document.createElement and appendChild eliminates virtual DOM overhead and reduces bundle size.
  • Plain ES modules house all UI logic without JSX or component abstractions, as seen in src/ui.js and src/main.js.
  • Manual event binding via addEventListener provides predictable interaction handling without synthetic event systems.
  • CSS custom properties allow JavaScript to control layout dynamically while keeping styling externalized in src/ui.css.
  • Custom manager classes like MapStackController and StyleManager replace framework-specific state management with simple JavaScript objects and custom events.
  • Native SVG and DOM overlays integrate seamlessly with Cesium's render loop without requiring framework reconciliation.

Frequently Asked Questions

Why does God’s Eye View avoid React or Vue for its UI?

God’s Eye View skips React, Vue, and similar frameworks to maintain a minimal bundle size and eliminate virtual DOM overhead. Since the application renders a performance-critical 3-D globe using Cesium, direct DOM manipulation ensures UI updates never block the main thread or introduce garbage collection pauses from framework abstractions.

How does the application handle state changes without a framework store?

The codebase uses custom manager classes such as DataLayerManager and MapStackController that expose simple methods like onChange and setStack. These classes fire standard JavaScript CustomEvent instances that UI components listen for using addEventListener, as implemented in src/main.js and related modules.

Can this no-framework approach scale to larger applications?

While God’s Eye View proves the pattern works for complex geospatial visualization, scaling requires strict organizational discipline. The project mitigates complexity by separating concerns into focused modules (src/ui.js for widgets, src/data/manager.js for state) and using consistent naming conventions for CSS classes and DOM IDs.

How are UI elements positioned relative to the 3-D globe?

UI overlays like annotations are rendered as absolute-positioned DOM elements or SVG layers that sit above the Cesium canvas. The screenAnnotationRenderer.js file calculates screen coordinates from world positions each frame and updates CSS transforms directly on the DOM nodes, bypassing any reconciliation layer.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →