HTML Package Bundle is a specification and toolset for creating self-contained, single-file HTML applications that bundle together a complete JavaScript package with source files and development capabilities.
- Overview
- Core Features
- Format Specification
- Environment Support
- WebContainer Integration
- Command Line Tools
- Runtime Behavior
- Design Principles
- Getting Started
- API Reference
- Browser Compatibility
- Implementation Status
- Architecture
HTML Package Bundle enables developers to create and distribute single-file web applications that include their complete source code and development environment. It combines the simplicity of sharing a single HTML file with the power of a complete JavaScript package, allowing end users to run, modify, and redeploy applications without requiring a local development environment.
This project draws inspiration from tools like TiddlyWiki (self-contained editable files) and leverages modern web technologies like WebContainer to provide a complete development experience within a browser.
- Self-Contained: Everything needed to run and modify the application is stored in a single HTML file
- Environment-Aware: Detects and adapts to different contexts (file://, localhost, https://)
- Self-Modifying: Uses the File System Access API to save changes back to itself
- Development Tools: Includes a built-in editor, file manager, and terminal
- WebContainer Integration: Runs a complete Node.js environment within the browser
- Offline-First: Works without an internet connection for core functionality
- Export Options: Export as a ZIP package or directly to a Git repository
An HTML Package Bundle file follows this structure:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Package Bundle</title>
<!-- Cross-origin isolation headers required for WebContainer -->
<meta http-equiv="Cross-Origin-Opener-Policy" content="same-origin">
<meta http-equiv="Cross-Origin-Embedder-Policy" content="require-corp">
<!-- Styles and essential scripts -->
<style>
/* Core application styles */
</style>
</head>
<body>
<!-- Application content (UI for the bundled application) -->
<div id="app">
<!-- App interface renders here -->
</div>
<!-- Environment information and controls -->
<div id="environment-info" class="info-panel">
<!-- Shows current environment, available features -->
</div>
<!-- Runtime application code (compiled/transpiled) -->
<script id="appCompiled" type="module">
// This is the compiled/transpiled application code for quick load
// It runs when the HTML file is opened
// Entry point for the runtime application
</script>
<!-- Development tools loader (only activated when requested) -->
<script id="devtools-loader">
// Lazy-loads the development environment when user enters edit mode
// Initializes editor, WebContainer, and other dev tools
</script>
<!-- Source bundle (loaded on-demand when editing) -->
<script id="source-bundle-data" type="application/json">
{
"version": "0.1.0",
"files": [
{"path": "src/index.js", "content": "// Main application code", "lastModified": 1234567890},
{"path": "package.json", "content": "{\n \"name\": \"example-app\",\n \"version\": \"1.0.0\",\n \"type\": \"module\",\n \"dependencies\": {\n \"lodash\": \"^4.17.21\"\n },\n \"scripts\": {\n \"dev\": \"vite\",\n \"build\": \"vite build\"\n }\n}", "lastModified": 1234567890},
{"path": "index.html", "content": "<!DOCTYPE html>\\n<html>\\n<head>\\n <title>App</title>\\n</head>\\n<body>\\n <div id=\\\"root\\\"></div>\\n <script type=\\\"module\\\" src=\\\"/src/index.js\\\"></script>\\n</body>\\n</html>", "lastModified": 1234567890},
{"path": "README.md", "content": "# Example App\\n\\nThis is a sample application bundled in an HTML Package Bundle.\\n\\n## Development\\n\\nEdit files using the built-in editor, or export to develop locally.", "lastModified": 1234567890}
],
"createdAt": 1234567890,
"updatedAt": 1234567890,
"metadata": {
"title": "Example Application",
"description": "A sample HTML Package Bundle",
"author": "HTML Package Bundle"
}
}
</script>
</body>
</html>
- Runtime Application: The compiled application code that runs immediately when the file is opened
- Source Bundle: JSON-formatted source files stored in a hidden script tag
- DevTools Loader: Code that initializes the development environment when requested
This structure enables optimized performance by:
- Loading only the compiled application for normal usage
- Loading development tools and source files only when needed
- Maintaining a clear separation between runtime and development components
HTML Package Bundle detects and adapts to different execution environments:
When opened from a local file:
- Main application runs normally
- File System Access API is used for self-modification (supported in Chrome/Edge)
- External network resources may be restricted
- Service Workers are unavailable
- Falls back to download mechanism for saving in unsupported browsers
Localhost (http://localhost)
When served from localhost:
- Full functionality available
- Considered a secure context by browsers
- Service Workers enabled
- WebContainer functionality available
- Ideal for development
When served from a secure domain:
- Full functionality available
- Service Workers enabled
- WebContainer functionality available
- Additional PWA capabilities possible
HTML Package Bundle uses WebContainer.io to provide a complete Node.js development environment in the browser:
- In-Browser Node.js: Runs a full Node.js environment via WebAssembly
- Package Management: Supports installing dependencies using pnpm/npm
- Virtual Filesystem: Populates a virtual filesystem with the bundled source files
- Terminal Access: Provides a terminal interface for running commands
- Development Server: Runs Vite or other development servers with live preview
Technical requirements for WebContainer support:
- Modern browser with Service Worker and SharedArrayBuffer support
- Cross-origin isolation headers (for SharedArrayBuffer):
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
- Secure context (HTTPS or localhost)
HTML Package Bundle provides CLI tools for creating and working with bundle files:
# Install the HTML Package Bundle CLI
npm install -g html-package-bundle
# Create a new bundle from an existing project
html-package-bundle pack ./my-project --output=my-app.html
# Create a bundle with a specific template
html-package-bundle pack ./my-project --template=minimal --output=my-app.html
# Exclude certain files from the bundle
html-package-bundle pack ./my-project --ignore="node_modules/**,*.log,dist/**" --output=my-app.html
# Extract a bundle to a directory
html-package-bundle unpack ./my-app.html --output=./extracted-project
# Force overwrite of existing files when extracting
html-package-bundle unpack ./my-app.html --output=./extracted-project --force
# Export project as a ZIP file
html-package-bundle export ./my-app.html --output=./my-project.zip
The HTML Package Bundle CLI offers several commands and options:
Packages a directory into an HTML bundle.
Options:
--output, -o
: Specify output HTML file path--template, -t
: Select a template (minimal, standard, full)--ignore, -i
: Glob patterns to exclude files--title
: Set the HTML title
Extracts an HTML bundle to a directory.
Options:
--output, -o
: Specify output directory path--force, -f
: Force overwrite of existing files
Exports a project to ZIP format.
Options:
--output, -o
: Specify output ZIP file path
When an HTML Package Bundle file is opened in a browser:
-
Regular Mode:
- The compiled application code runs immediately
- Source bundle remains dormant to save resources
- A gear icon ⚙️ provides access to developer tools
-
Development Mode (accessed via gear icon):
- Code editor loads for modifying source files
- WebContainer initializes (if in a compatible environment)
- Files from the source bundle are mounted in the virtual filesystem
- Dependencies can be installed from npm
- Development server can be started with live preview
- Terminal provides command-line access
-
Save Operations:
- Direct file modification using File System Access API
- Download as a new HTML file (fallback for browsers without FS Access)
- Export as a ZIP package of source files
- Optionally push to a Git repository (advanced feature)
HTML Package Bundle adheres to the following design principles:
- Single File Philosophy: Everything needed should be in one file for easy sharing
- Progressive Enhancement: Core functionality works everywhere; advanced features load when supported
- Performance First: Lazy loading of development tools and source code
- Offline-First: Core functionality works without internet access
- User Agency: End users can view, modify, and redistribute the application
- Seamless Developer Experience: Provide familiar development tools within the browser
- Secure by Design: Sandbox execution and follow secure coding practices
-
Install the HTML Package Bundle toolkit:
npm install -g html-package-bundle
-
Create a new bundle from an existing project:
html-package-bundle pack ./my-project
-
Open the resulting HTML file in a supported browser
- Open the HTML file in a supported browser
- Use the application as normal
- Click the gear icon ⚙️ to access developer tools
- Modify source files in the editor
- Save changes back to the HTML file
HTML Package Bundle exposes several JavaScript APIs for working with bundles:
interface Environment {
protocol: string;
isFileProtocol: boolean;
isLocalhost: boolean;
isHTTPS: boolean;
canLoadExternalResources: boolean;
hasFileSystemAccess: boolean;
hasIndexedDB: boolean;
}
function detectEnvironment(): Environment;
/**
* Represents a single file within the source bundle
*/
interface SourceFile {
/** Relative path to the file (e.g., "src/index.js") */
path: string;
/** Raw content of the file as a string */
content: string;
/** Timestamp when the file was last modified */
lastModified: number;
}
/**
* Represents the complete source bundle stored in the HTML
*/
interface SourceBundle {
/** Version of the bundle format */
version: string;
/** Array of source files */
files: SourceFile[];
/** Timestamp when the bundle was created */
createdAt: number;
/** Timestamp when the bundle was last updated */
updatedAt: number;
/** Optional metadata about the project */
metadata?: {
title?: string;
description?: string;
author?: string;
[key: string]: any;
};
}
/**
* Manages the source bundle stored within the HTML file
*/
class SourceBundleManager {
/**
* Initializes the source bundle from the HTML document
* @returns true if successful, false otherwise
*/
initialize(): boolean;
/**
* Gets all files in the bundle
* @returns Array of source files
*/
getFiles(): SourceFile[];
/**
* Gets a specific file by path
* @param path The file path to retrieve
* @returns The file if found, undefined otherwise
*/
getFile(path: string): SourceFile | undefined;
/**
* Adds or updates a file in the bundle
* @param path The file path
* @param content The file content
*/
addFile(path: string, content: string): void;
/**
* Removes a file from the bundle
* @param path The file path to remove
* @returns true if successfully removed, false if not found
*/
removeFile(path: string): boolean;
/**
* Exports the bundle as a JSON string
* @returns JSON representation of the bundle
*/
exportBundle(): string;
/**
* Imports a bundle from a JSON string
* @param json The JSON string to import
* @returns true if successful, false otherwise
*/
importBundle(json: string): boolean;
/**
* Gets file paths matching a glob pattern
* @param pattern The glob pattern to match
* @returns Array of matching file paths
*/
findFiles(pattern: string): string[];
}
interface WebContainerState {
isInitialized: boolean;
isBooting: boolean;
isServerRunning: boolean;
terminal: HTMLElement | null;
serverUrl: string | null;
error: string | null;
}
class WebContainerManager {
initialize(): Promise<boolean>;
mountFiles(files: SourceFile[]): Promise<boolean>;
installDependencies(): Promise<boolean>;
startDevServer(): Promise<boolean>;
executeCommand(command: string, args: string[]): Promise<{ success: boolean; output: string }>;
writeFile(path: string, content: string): Promise<boolean>;
readFile(path: string): Promise<string | null>;
getServerUrl(): string | null;
}
HTML Package Bundle is compatible with modern browsers, with different levels of functionality:
Feature | Chrome | Edge | Firefox | Safari |
---|---|---|---|---|
Basic application | ✅ | ✅ | ✅ | ✅ |
File System Access API | ✅ | ✅ | ❌ | |
WebContainer | ✅ | ✅ | ❌ | |
IndexedDB | ✅ | ✅ | ✅ | ✅ |
ESM Modules | ✅ | ✅ | ✅ | ✅ |
Legend: ✅ Full support,
The HTML Package Bundle project is currently in active development. Below is the status of key features:
- ✅ Basic Structure & Environment Detection
- HTML structure with runtime application and source code bundle
- Environment detection for file://, localhost, and https:// protocols
- UI adaptation based on environment
- ✅ Self-Modification System
- File System Access API integration with permission management
- File handle persistence in IndexedDB
- Fallback download mechanism for unsupported browsers
- ✅ Source Code Management
- JSON structure for storing source files in HTML
- Code editor integration (CodeMirror)
- File navigation and editing capabilities
- ✅ WebContainer Integration
- In-browser Node.js environment with WebContainer.io
- Virtual filesystem from embedded source files
- Package management with pnpm
- Terminal/console interface
- Preview system for running applications
- 🔄 Versioning and change tracking system
- 🔄 Bi-directional sync between editor and WebContainer
- 🔄 Build system to update runtime code from source
- ⏳ Export as ZIP package
- ⏳ Git integration
- ⏳ Performance optimizations and caching strategies
- ⏳ Enhanced documentation and examples
The HTML Package Bundle uses a modular architecture with well-defined components:
-
Environment Detector
- Detects the current browser environment (protocol, features)
- Determines which capabilities are available
- Guides feature availability and UI adaptation
-
Source Bundle Manager
- Stores and manages source files embedded in the HTML
- Provides an interface for adding, retrieving, and updating files
- Handles serialization/deserialization of file data
-
File System Manager
- Interfaces with the File System Access API
- Manages file handles and permissions
- Provides file reading/writing capabilities
- Handles HTML file validation and fallback saving
-
Editor Manager
- Provides code editing UI (CodeMirror)
- Syntax highlighting and editing features
- File opening/closing workflow
-
WebContainer Manager
- Initializes and manages WebContainer instance
- Mounts source files to virtual filesystem
- Handles package installation
- Manages terminal output and development server
- Source files are stored in a hidden
<script>
element within the HTML - User edits files through the editor interface
- Changes are stored in the source bundle
- When saving, the entire HTML is regenerated and written to disk
- For development, WebContainer mounts files for runtime usage
- Opening a file: User selects a file from the source bundle, Editor Manager displays it
- Saving changes: Editor saves to Source Bundle Manager, UI refreshes
- Self-modification: File System Manager writes new HTML bundle to disk
- Development: WebContainer mounts files, installs dependencies, runs servers
This project is licensed under the MIT License - see the LICENSE file for details.