QIP Docs
The Problem With Software Today #
Much software is built as layers of frameworks, packages, platforms, and operating-system features. The result is often non-deterministic in practice: behavior can depend on installed packages, environment variables, filesystem layout, network services, locale, clocks, and the exact setup of the machine around it.
Containers can package that environment, which is useful for full applications. For a content transform, validator, image filter, or small interactive tool, it is often more machinery than the work needs.
AI coding raises the stakes. Agents can generate useful code quickly, but that code is easier to review and test when its inputs, outputs, memory, and host access are explicit.
The QIP Values #
QIP is named for the constraints we want every component to keep:
- Quarantined: components run in a deterministic sandbox with zero access to the host: no filesystem, no network, and no environment.
- Immutable: components are self-contained with no required dependencies, so once you have a working component it keeps working with no updates required.
- Portable: components run identically across web and native hosts through the same QIP contract.
Why WebAssembly #
WebAssembly gives QIP a compact, portable execution target.
A QIP component is a WebAssembly binary with explicit imports and exports. By default, QIP gives it no filesystem, network, environment, clock, or secrets. The host writes input bytes into component memory, calls a known export such as render(input_size), then reads output bytes back.
That shape gives the host a deterministic execution boundary: the same component bytes and input bytes are guaranteed produce the same output bytes. Components stay small enough to test, benchmark, and replace when better code appears.
Why Not WASI #
WASI is useful when a program needs operating-system-like capabilities. QIP is deliberately narrower.
For QIP components, the default should be no ambient host access. If a component transforms Markdown, validates UTF-8, renders an image tile, or emits an interactive frame, it should not need file descriptors, sockets, environment variables, or a virtual filesystem.
This smaller contract is less general, but it is easier to run in browsers, easier to inspect, and easier to explain to coding agents.
Content-First, Not File-First #
QIP treats content as bytes with media types, not as files with special build-system meaning.
That is why recipes are selected by MIME type, why Content components can convert/assert/refine a pipeline, and why router output can be represented as application/warc instead of a particular static-file layout.
For example, qip router warc ./site produces a Web Archive. Another component can turn that archive into a static tarball, check links, add derived metadata, or prepare it for a deployment target.
Adopting QIP In An Existing App #
QIP fits into existing apps when a small content transform should work the same across platforms, or when generated code should run without filesystem, network, environment, or secret access.
Keep the app in charge of routing, auth, storage, and product workflow. Move a small deterministic transformation into a QIP component: render Markdown, validate HTML, normalize an identifier, transform an image, or generate a QR code. The component gets only the bytes the app passes in, and the app gets portable behavior it can test by comparing output bytes.
See Adopting QIP In Existing Apps for the practical checklist.