Skip to main content

Overview

Blank Board uses a micro-kernel architecture. The kernel handles bootstrapping and plugin loading. Everything else is a plugin.

Core Files

index.html

The only static HTML file. Contains:
  • A #board div (100vw × 100vh) with a CSS grid background
  • Base styles for .plugin-box (positioned, draggable containers)
  • A single <script type="module"> that boots core/core.js

core/core.js — Bootstrap

The entry point. On load:
  1. Creates the EventBus instance
  2. Creates a storage adapter (localStorage wrapper)
  3. Calls createApi() to build the plugin API (version "4.0.0")
  4. Loads the plugin registry from localStorage
  5. Auto-installs or re-enables the Plugin Manager if missing/disabled
  6. Iterates through enabled plugins and loads each via dynamic import()
  7. Handles CORS by fetching remote plugin code and loading via blob URLs
  8. Deduplicates the registry
  9. Emits board:allPluginsLoaded after all plugins load
  10. Attaches management methods (togglePlugin, deletePlugin, installPlugin, reloadPlugin, restart)
  11. Exposes window.blankBoard = { bus, api } for debugging

core/api.js — API Factory

Creates the API object passed to every plugin’s setup() function. Includes:
  • Container management (container getter, getContainer, mountPlugin, undockPlugin, updatePlugin)
  • CSS injection (injectCSS, removeCSS)
  • UI systems (toolbar, sidebar, context menu, notifications, modals, shortcuts)
  • Hooks system (registerHook, useHook, removeHook)
  • Storage (global + plugin-scoped)
  • Permissions system
  • Drag & resize helpers
  • Utility functions (debounce, throttle)

core/eventBus.js — Event System

A minimal pub/sub with: on(), off(), once(), emit(), removeAll().

Plugin File Format

Every plugin is a standalone ES module:

Plugin Registry

Stored in localStorage under board-plugins-registry:

Registry Fields

Lifecycle

Plugin Loading (CORS Handling)

For cross-origin plugin URLs, the core:
  1. Fetches the plugin code via fetch()
  2. Creates a Blob with application/javascript type
  3. Generates a blob URL via URL.createObjectURL()
  4. Imports the blob URL
  5. Revokes the blob URL after import
This allows loading plugins from any CORS-enabled server (like GitHub raw URLs).

File Tree

Plugins are no longer bundled in the main repository. They live in the community plugin repo and are loaded via URL.