Overview
PortableWeb defines a file format for packaging interactive web content —
HTML, CSS, JavaScript, and associated media — into a single self-contained,
portable bundle. A PortableWeb bundle (.pweb file) can be saved, shared,
and rendered by a compatible viewer on any platform, entirely offline, without a web
server, without association with a Web origin, and without being confined to a web
browser.
This document defines the container format and manifest schema for PortableWeb bundles at spec version 0.1. Companion specifications covering the runtime sandbox, storage model, cryptographic signing, and inter-bundle communication are forthcoming and out of scope here.
The format is content-model agnostic: a bundle may contain a book, a game, an interactive presentation, an educational simulation, a 3D experience, a scientific model, a collaborative application, or any other interactive content built on web technologies. The format imposes no constraints on the content model.
Design goals
The PortableWeb format is designed to:
- Be openable by any compatible viewer on any platform, entirely offline.
- Behave like a document: saveable, copyable, shareable, and archivable.
- Support any interactive content built on standard web technologies.
- Operate without a Web origin and without being confined to a web browser.
- Declare capabilities and permissions upfront in a structured manifest.
- Provide a stable, versioned format with long-term backwards compatibility.
- Be identifiable without unpacking, via magic bytes and a
mimetypeentry. - Remain simple enough that a conforming implementation can be built quickly.
Terminology
The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in BCP 14 (RFC 2119, RFC 8174) when, and only when, they appear in all capitals.
- PortableWeb
- Short form of “Portable Web Content Format,” the file format defined by this specification.
- Bundle
- A single
.pwebfile conforming to this specification. - Viewer
- Software that opens, renders, and sandboxes a bundle.
- Manifest
- The
manifest.jsonfile at the root of a bundle archive. - Entry file
- The HTML file the viewer loads first, declared in the manifest's
entryfield. - Package boundary
- The set of files contained within a bundle. Resources outside this boundary are external resources.
Container format
3.1 · File extension & media type
A PortableWeb bundle uses the following identifiers:
- File extension:
.pweb - Media type:
application/vnd.portableweb+zip - Magic bytes:
50 4B 03 04(PK\003\004) — the standard ZIP local file header signature.
A viewer MUST accept files with the .pweb extension or the
application/vnd.portableweb+zip media type, and SHOULD also
identify bundles by inspecting the mimetype entry described below.
3.2 · Outer container
A bundle MUST be a valid ZIP archive. The ISO/IEC 21320-1 Document
Container File profile is RECOMMENDED. Specifically: the archive MUST NOT
be encrypted or split across multiple files; file and directory names MUST
use forward slashes as path separators, encoded in UTF-8; and the archive
SHOULD NOT contain absolute paths or .. path components.
3.3 · The mimetype entry
A bundle MUST contain a file named mimetype at the archive root with these properties:
- Contents: the ASCII string
application/vnd.portableweb+zip, with no trailing newline or whitespace. - Position: the first entry in the ZIP archive.
- Compression: STORED (method 0, uncompressed).
- No extra fields in the local file header.
This convention, borrowed from EPUB, lets a tool identify a PortableWeb bundle by reading the first ~80 bytes of the file without unpacking the archive.
3.4 – 3.5 · manifest.json and the entry file
A bundle MUST contain a manifest.json file at the archive
root, encoded as UTF-8 JSON without a byte order mark, declaring at minimum the spec
version, a unique bundle identifier, the bundle version, a title, the entry file path,
and any declared permissions (schema in §4).
A bundle MUST contain the file referenced by the manifest's
entry field. The entry file MUST have a .html
or .htm extension and MUST be valid HTML5. It is loaded by
the viewer in a sandboxed context; all other files in the bundle are addressable from it
using relative paths.
3.6 · Recommended file layout
The following layout is RECOMMENDED but not required — bundles MAY use any layout consistent with this section.
entry).3.7 · Reserved paths
The following paths at the archive root are reserved. Bundles SHOULD NOT
create files at these paths unless following an explicit PortableWeb sub-specification:
mimetype, manifest.json, META-INF/ (reserved for
signature manifests and integrity data), and .well-known/ (reserved for
future use).
3.8 · Bundle identification
A viewer SHOULD identify a file as a PortableWeb bundle if the file
extension is .pweb, the declared media type is
application/vnd.portableweb+zip, or the first ZIP entry is a STORED file
named mimetype containing exactly that string. A viewer
SHOULD reject any file claiming to be a PortableWeb bundle that fails
to validate against this section.
3.9 · Versioning
The container format is versioned independently from companion specifications; this
document describes container version 0.1. Future container versions
MUST remain backwards compatible — a bundle declaring
spec_version: "1.0" in its manifest MUST remain openable
by any future viewer that claims support for v1.0 bundles. New features are added in
new spec versions; existing features are not removed. This guarantee is the foundation
of the PortableWeb archival promise.
Manifest schema
Every bundle contains a manifest.json at its archive root: structured
metadata that identifies the bundle, declares its entry point, specifies requested
permissions, and carries rights and authorship information. It MUST
be a valid JSON object, UTF-8 encoded, without a byte order mark.
4.3 · Required fields
| Field | Type | Description |
|---|---|---|
| spec_version | string | The container spec version this bundle targets. Format "MAJOR.MINOR". For v0.1 bundles, MUST be "0.1". |
| id | string | A globally unique identifier in reverse-domain notation (e.g. "org.example.my-bundle"). Lowercase alphanumeric, dots, and hyphens only. |
| version | string | The bundle's own version, following Semantic Versioning 2.0 (e.g. "1.0.0"). |
| title | string | A human-readable title. MUST NOT exceed 200 characters. |
| entry | string | Path within the bundle to the HTML entry file. MUST end in .html or .htm; MUST NOT begin with /. |
4.4 · Recommended fields
| Field | Type | Description |
|---|---|---|
| description | string | A short description of the bundle. Max 1000 characters. |
| author | object | name (required), email (optional), url (optional). |
| created | string | Creation date, ISO 8601 (e.g. "2026-05-24T00:00:00Z"). |
| icon | string | Path within the bundle to a square icon (SVG or PNG recommended). |
| permissions | object | Declared capabilities — see the permissions table. If omitted, all permissions default to their specified defaults. |
| rights | object | Copyright and license information — see below. |
| viewport | object | Hints to the viewer for initial window sizing — see below. |
| content_type | string | A hint describing the content's nature. Recommended values: game, presentation, book, simulation, tool, report, visualization, education. |
4.5 · Permissions
Permissions are declared upfront in the manifest and are not requested at runtime. Any permission not declared is denied by default. Viewers SHOULD present declared permissions to the user when a bundle is first opened.
| Permission | Type | Default | Description |
|---|---|---|---|
| network | boolean | false | Allow fetch / XMLHttpRequest to non-bundle URLs. Archival bundles SHOULD keep this false. |
| camera | boolean | string | false | Allow getUserMedia video access. A string value is shown to the user as a justification. |
| microphone | boolean | string | false | Allow getUserMedia audio access. |
| geolocation | boolean | string | false | Allow the Geolocation API. |
| clipboard_write | boolean | false | Allow programmatic writes to the system clipboard. |
| notifications | boolean | false | Allow OS-level notifications while the bundle is open. |
| fullscreen | boolean | true | Allow the Fullscreen API. Defaults true due to low risk. |
| storage | string | "isolated" | "none" (no persistent storage) or "isolated" (scoped localStorage/IndexedDB, isolated per bundle). |
| peers | boolean | false | Allow inter-bundle communication via local channels. Defined in the companion COMMS specification. |
Future versions of this specification MAY define additional permission keys. Viewers MUST ignore unknown permission keys when the bundle targets a spec version the viewer supports.
4.6 · The rights object
| Field | Type | Description |
|---|---|---|
| copyright | string | Human-readable copyright notice (e.g. "© 2026 Jane Doe"). |
| license | string | An SPDX license identifier (e.g. "MIT", "CC-BY-4.0", "CC0-1.0", "proprietary"). |
| license_url | string | URL to the full license text. |
| contact | string | Contact information for licensing inquiries. |
4.7 · The viewport object
| Field | Type | Description |
|---|---|---|
| preferred_width | integer | Suggested initial window width in CSS pixels. |
| preferred_height | integer | Suggested initial window height in CSS pixels. |
| resizable | boolean | Whether the viewer window should be resizable. Default: true. |
| min_width | integer | Minimum window width in CSS pixels. |
| min_height | integer | Minimum window height in CSS pixels. |
These are hints, not requirements — viewers MAY override them based on the user's environment or platform conventions.
4.8 · Example: minimal valid manifest
{
"spec_version": "0.1",
"id": "org.example.minimal",
"version": "1.0.0",
"title": "Minimal Example",
"entry": "index.html"
}
4.9 · Example: full manifest
{
"spec_version": "0.1",
"id": "org.example.solar-system",
"version": "1.2.0",
"title": "Interactive Solar System",
"description": "Explore planet orbits and relative scales.",
"content_type": "simulation",
"author": {
"name": "Jane Doe",
"email": "jane@example.com",
"url": "https://janedoe.example.com"
},
"created": "2026-05-24T00:00:00Z",
"icon": "assets/icon.svg",
"entry": "index.html",
"permissions": {
"network": false,
"camera": false,
"microphone": false,
"storage": "isolated",
"fullscreen": true,
"peers": false
},
"rights": {
"copyright": "© 2026 Jane Doe",
"license": "CC-BY-4.0",
"license_url": "https://creativecommons.org/licenses/by/4.0/"
},
"viewport": {
"preferred_width": 1280,
"preferred_height": 800,
"resizable": true,
"min_width": 800,
"min_height": 600
}
}
4.10 · Validation
Viewers and tools SHOULD validate manifests against the schema before
opening a bundle. A formal JSON Schema document for this manifest will be published at
portableweb.org/spec/manifest.schema.json. In the meantime, the
web app's Validate tool runs the equivalent checks client-side.
Interoperability considerations
Interoperability depends on viewers interpreting the manifest consistently, resolving resource paths consistently, and enforcing package boundaries consistently.
Implementations SHOULD use UTF-8 for manifest data and resource
identifiers. Resource paths SHOULD be treated as case-sensitive,
package-relative paths. Implementations SHOULD avoid relying on
platform-specific filesystem behavior such as case-insensitive path matching, absolute
paths, drive letters, symbolic links, or path separators other than /.
Viewers SHOULD reject or normalize ambiguous paths, duplicate entries,
and references that resolve outside the package boundary.
Bundles may contain common web resource formats including HTML, CSS, JavaScript, JSON, images, fonts, audio, and video. Rendering behavior may vary between web engines and viewer implementations, particularly for optional platform features, media codecs, and device APIs. Bundle authors SHOULD use widely supported web standards and SHOULD declare required or requested capabilities in the manifest. Viewers SHOULD ignore unknown manifest fields that are not required for safe processing.
A conforming local PortableWeb bundle SHOULD be interpretable using only the resources it contains, unless the manifest and viewer policy explicitly allow external network access.
Security considerations
6.1 · Untrusted by default
PortableWeb packages can contain active or executable web content, including HTML, ECMAScript/JavaScript and, where supported by the viewer, WebAssembly. Implementations must treat PortableWeb packages as untrusted input unless the source and integrity of the package have been independently established.
6.2 · Sandboxed execution & capability requests
A viewer that executes active content must isolate that content from the viewer application and the host environment. Packaged content must not receive ambient access to local files, host credentials, cookies, application data, device APIs, persistent storage, network resources, the clipboard, downloads, popups, external navigation, or privileged host APIs. Access to such capabilities must be explicitly permitted by both the viewer or user policy and, where applicable, the package manifest. Manifest capability declarations are requests and must not be treated as authorization. A viewer may deny or further restrict any requested capability.
6.3 · Confidentiality, integrity & trust
PortableWeb packages may contain private or sensitive information, and the safe behavior of active content may depend on the integrity of the package. This media type does not itself provide confidentiality, integrity, authentication, authorization, or replay protection. When those properties are required, they must be provided externally, for example through TLS during transport, a trusted distribution channel, operating-system file protections, checksums, digital signatures, or application-level validation.
6.4 · Container & resource format security
PortableWeb uses a ZIP container and a JSON manifest and may contain HTML, CSS, JavaScript, WebAssembly, images, fonts, audio, video, and other media. The security considerations of ZIP, JSON, and each embedded resource format apply. Implementations must parse the manifest strictly, validate resource references against the manifest and package boundaries, avoid unsafe content sniffing, and must not grant privileges based only on a filename extension or declared media type.
6.5 · Compression & archive safety
Because PortableWeb uses compression and the ZIP container format, implementations must protect against decompression bombs, excessive memory or storage consumption, deeply nested archives, duplicate or ambiguous entry names, absolute paths, path traversal, symbolic links, filename-normalization conflicts, and inconsistencies between ZIP metadata and actual content. Implementations must impose limits on uncompressed size, file count, nesting depth, path length, and individual resource size. Extracted resources must remain within an application-controlled location.
6.6 · External resources & local-first operation
A conforming local PortableWeb package can be interpreted using only the resources contained within the package. Packages may contain optional external links, but external resources are not required to interpret the local package. When external network access or navigation is permitted, the viewer must distinguish external resources from packaged resources and mediate access according to the viewer or user policy.
IANA considerations
The specification registers the following media type in the vendor tree:
| Type name | application |
| Subtype name | vnd.portableweb+zip |
| Required parameters | None |
| Encoding | Binary |
| Magic number(s) | 50 4B 03 04 (PK\003\004) |
| File extension(s) | .pweb |
| Intended usage | COMMON |
| Contact | Omprakash Selvaraj, maintainer@portableweb.org |
| Change controller | Omprakash Selvaraj |
Applications that use this media type: PortableWeb viewer applications, authoring tools, packaging tools, validation tools, document-management systems, file managers, web servers, content-distribution systems, and AI content generation tools that create, distribute, inspect, validate, store, or render PortableWeb packages.
References
Normative
- [ISO21320]
- ISO/IEC 21320-1: Document Container File — Part 1: Core, 2015.
- [RFC2119]
- Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels,” BCP 14, RFC 2119, March 1997.
- [RFC8174]
- Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words,” BCP 14, RFC 8174, May 2017.
- [RFC8259]
- Bray, T., “The JavaScript Object Notation (JSON) Data Interchange Format,” December 2017.
Informative
- [EPUB3]
- “EPUB 3.3,” W3C, 2023.
- [SEMVER]
- “Semantic Versioning 2.0.0,” 2013.
- [SPDX]
- “SPDX License List.”
- [WAM]
- “Web Application Manifest,” W3C, 2023.
- [WASM]
- “WebAssembly Core Specification,” W3C, 2022.
- [ZIP]
- APPNOTE.TXT — .ZIP File Format Specification.
Status & versioning
This is spec version 0.1. It is registered as an IETF Internet-Draft, submitted as an Independent Submission under BCP 78/79 — a formal but still-evolving public record of the format, open to feedback and revision as it progresses toward a stable v1.0.
The broader format — the runtime sandbox, the frozen per-version feature subset, cryptographic signing, storage isolation, and inter-bundle communication — is out of scope for this document and is being developed in companion specifications through the W3C Portable Web Content Format Community Group, open to anyone.
Container versions are append-only: new spec versions add features without removing or
breaking existing ones, so a bundle that declares spec_version: "1.0" will
keep rendering correctly in any v1.0-compatible viewer, indefinitely. This is the basis
of the format's archival guarantee.