Skip to content

Micro Apps

A micro app is an independently built and deployed frontend application that integrates with the Tuvix.js shell via a standard lifecycle interface.

The MicroApp Interface

ts
interface MicroApp {
  mount(container: HTMLElement, props?: Record<string, unknown>): Promise<void>;
  unmount(container: HTMLElement): Promise<void>;
  update?(container: HTMLElement, props?: Record<string, unknown>): Promise<void>;
}

Your micro app bundle must export an object that satisfies this interface.

Vanilla JS Example

ts
// my-app/main.ts
import type { MicroApp } from '@tuvix.js/core';

export const app: MicroApp = {
  async mount(container, props) {
    const div = document.createElement('div');
    div.className = 'my-app';
    div.innerHTML = `<h1>Hello from My App</h1>`;
    container.appendChild(div);
  },

  async unmount(container) {
    container.innerHTML = '';
  },
};

Passing Props

The shell can pass props to micro apps at registration time or dynamically:

ts
// Shell
orchestrator.register('profile', {
  entry: '/profile.js',
  props: {
    userId: getCurrentUserId(),
    theme: 'dark',
  },
});
ts
// Micro app receives props in mount()
export const app: MicroApp = {
  async mount(container, props) {
    const { userId, theme } = props as { userId: string; theme: string };
    // render with props
  },
};

Building for Production

Each micro app is built to a standalone JavaScript bundle. Use any bundler:

Vite

ts
// vite.config.ts
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    lib: {
      entry: './src/main.ts',
      name: 'MyApp',
      formats: ['es'],
    },
    rollupOptions: {
      // Externalize framework to avoid duplication
      external: ['react', 'react-dom'],
    },
  },
});

Webpack

js
// webpack.config.js
module.exports = {
  entry: './src/main.ts',
  output: {
    library: { type: 'module' },
    filename: 'main.js',
  },
  experiments: { outputModule: true },
};

Released under the MIT License.