Switch Framework

0.2.5 · maintenance · verified Sun Apr 19

Switch Framework (version 0.2.5) is an early-stage frontend library designed for building web and Electron desktop applications. It emphasizes a "runtime-first" development workflow, aiming to allow applications to run without a traditional build step or bundler for basic setups. This approach means the framework is served and executed directly at runtime. It is intended to work in conjunction with `switch-framework-backend` for full functionality. The project is currently under active maintenance, but official documentation is not yet complete. Key differentiators include its bundler-less initial setup and specific targeting of both web and Electron environments, alongside a component-based architecture featuring integrated state management utilities. The framework is primarily developed by Switcherfaiz and has a companion CLI tool, `create-switch-framework-app`, for project initialization.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates a minimal Switch Framework custom component, defining a reactive counter that updates its display upon interaction, utilizing the framework's state management and lifecycle methods.

import { SwitchComponent, createState, updateState, getState } from 'switch-framework';

// This example assumes it's loaded as a module in an HTML file.
// e.g., <script type="module" src="./app.js"></script>
// And a <sw-counter></sw-counter> element exists in the HTML body.

// Initialize a global reactive state named 'counterValue'
createState('counterValue', 0);

export class CounterComponent extends SwitchComponent {
  static tag = 'sw-counter'; // Define the custom element tag

  // Subscribe to state changes for automatic re-rendering
  static {
    this.useState('counterValue');
  }

  onMount() {
    // Attach a delegated click listener to the increment button
    this.listener('#incrementBtn', 'click', () => {
      // Update 'counterValue' state; (currentCount ?? 0) handles initial undefined
      updateState('counterValue', (currentCount) => (currentCount ?? 0) + 1);
    });
  }

  render(): string {
    const count = getState('counterValue') ?? 0;
    return `
      <style>
        .counter-wrapper {
          display: flex;
          flex-direction: column;
          align-items: center;
          padding: 20px;
          font-family: Arial, sans-serif;
          border: 1px solid #eee;
          border-radius: 8px;
          max-width: 300px;
          margin: 20px auto;
          box-shadow: 0 4px 8px rgba(0,0,0,0.1);
        }
        .counter-button {
          padding: 10px 20px;
          font-size: 1.2em;
          background-color: #007bff; /* Primary blue */
          color: white;
          border: none;
          border-radius: 5px;
          cursor: pointer;
          transition: background-color 0.3s ease;
        }
        .counter-button:hover {
          background-color: #0056b3;
        }
        .count-display {
          margin-top: 15px;
          font-size: 1.8em;
          font-weight: bold;
          color: #333;
        }
      </style>
      <div class="counter-wrapper">
        <button id="incrementBtn" class="counter-button">
          Click to Increment
        </button>
        <div class="count-display">
          Current Count: ${count}
        </div>
      </div>
    `;
  }
}

// Register the custom element once the class is defined
// Check if already defined to prevent errors in hot-reloading scenarios
if (!customElements.get(CounterComponent.tag)) {
  customElements.define(CounterComponent.tag, CounterComponent);
}

view raw JSON →