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
#boarddiv (100vw × 100vh) with a CSS grid background - Base styles for
.plugin-box(positioned, draggable containers) - A single
<script type="module">that bootscore/core.js
core/core.js — Bootstrap
The entry point. On load:
- Creates the EventBus instance
- Creates a storage adapter (localStorage wrapper)
- Calls
createApi()to build the plugin API (version"4.0.0") - Loads the plugin registry from localStorage
- Auto-installs or re-enables the Plugin Manager if missing/disabled
- Iterates through enabled plugins and loads each via dynamic
import() - Handles CORS by fetching remote plugin code and loading via blob URLs
- Deduplicates the registry
- Emits
board:allPluginsLoadedafter all plugins load - Attaches management methods (
togglePlugin,deletePlugin,installPlugin,reloadPlugin,restart) - 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 (
containergetter,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 underboard-plugins-registry:
Registry Fields
| Field | Required | Description |
|---|---|---|
id | ✅ | Unique plugin identifier |
url | ✅ | URL to the .js file |
name | ✅ | Display name |
enabled | ✅ | Whether the plugin is loaded |
source | ❌ | 'system', 'registry', or 'manual' |
Lifecycle
| Action | What Happens |
|---|---|
| First load | Plugin Manager auto-installed from GitHub |
| Subsequent loads | Reads from localStorage (persists changes) |
| Install | Appends to registry → saves → dynamic import |
| Toggle off | Calls teardown() → removes container → saves |
| Toggle on | Loads via import() → calls setup(api) |
| Delete | Unloads → removes from registry → saves |
| Restart | Unloads all → reloads all enabled |
Plugin Loading (CORS Handling)
For cross-origin plugin URLs, the core:- Fetches the plugin code via
fetch() - Creates a
Blobwithapplication/javascripttype - Generates a blob URL via
URL.createObjectURL() - Imports the blob URL
- Revokes the blob URL after import
File Tree
Plugins are no longer bundled in the main repository. They live in the community plugin repo and are loaded via URL.