Components that are
Quick to make/maintain/run, Isolated from net/disk/deps, Portable to web/server/native.

Read the docs

QIP components are fast to create with coding agents and fast for users to run.

Users get small .wasm modules that load quickly. You get code small enough to review.

Render across browser, server, mobile, native, CLI, and CI. Same input, same output everywhere.


Today we grant every line of code the world #

Most software is built with layers of frameworks, packages, platforms, and operating-system features. It means even a tiny calculation assumes availability of installed packages, environment variables, filesystem layout, network services, locale, clocks, and the exact setup of the machine around it.

Containers can precisely package that environment. This is useful for full applications, but for a text/image transformation, validator, calculation, or small interactive tool, it is often more machinery than the work requires. Our defaults expand the security boundary that every line of code gets and now AI coding raises the stakes.

QIP uses a narrower boundary: explicit input, output, memory, and zero host access. That makes small components easier to create, test, and review — including code written by coding agents.

Components that render any content #

Use QIP components for text, images, documents, archives, interactive UI, or any MIME type.

Just like the web is request -> response, QIP components are input -> output. Yet QIP components are not tied to HTML or JavaScript: they take any content as input and render any content as output.

Your components can render Markdown into HTML, URLs into QR codes, SVG into bitmap images, SQLite databases into CSV, or WARC archives into deployable websites. Missing something? Prompt a small component and add it to your collection.

echo "# A Markdown renderer that works _identically_ on any platform" \
| qip run components/text/markdown/gfm-commonmark.0.31.2.wasm
# <h1>A Markdown renderer that works <em>identically</em> on any platform<h1>

Portable pipelines of purity #

You can pipe one component into another step-by-step like a recipe.

Make a recipe you like? It will work identically on mobile, in a browser, in your CI pipeline, or on Windows. You can be confident if it works here, it works there.

For example, one component can render Markdown to HTML, then it passes that to the next component to highlight TSX code blocks:

printf '%s\n' \
  '# Markdown with code snippet' \
  '' \
  '```tsx' \
  'const pi: number = 3.14;' \
  '```' \
| qip run \
  components/text/markdown/gfm-commonmark.0.31.2.wasm \
  components/text/html/html-code-syntax-highlight-tsx.wasm

# <h1>Markdown with code snippet</h1>
# <pre><code class="language-tsx hljs"><span class="hljs-keyword">const</span> pi: <span class="hljs-type">number</span> = <span class="hljs-number">3.14</span>;
# </code></pre>

Browser rendering #

You can render the same QIP components in the browser:

HTML output

Use the <qip-edit> custom element to render a series of QIP components with user <input>.

<form aria-label="Markdown to HTML">
    <qip-edit>
        <source src="/components/text/markdown/gfm-commonmark.0.31.2.wasm" type="application/wasm" />
        <source src="/components/text/html/html-code-syntax-highlight-tsx.wasm" type="application/wasm" />
        <textarea name="input" rows="5"># Markdown with highlighted code
```tsx
const pi: number = 3.14;
```</textarea>
        <output name="output"><iframe title="Rendered HTML preview" sandbox></iframe></output>
    </qip-edit>
</form>

The website router without bitrot #

Markdown… Recipes… We can compose this into a static website generator. Each file gets rendered by a recipe of QIP components based on its MIME type. These become the HTTP response bodies.

Every component is replaceable. Don’t like the Markdown renderer? Swap it out.

And every page route becomes combined into a .warc Web Archive. This allows you to do site-wide transforms. Need a plugin to generate OG images? Vibe-code one.

First, create a folder of Markdown and images files and use qip router to render a website:

site/
  index.md
  about.md
  docs/index.md
  docs/install.md
  _recipes/text/markdown/10-commonmark.0.31.2.wasm
# Run a dev server on port 4114
qip router dev ./site -p 4114

# Make a HEAD request to the /about page
qip router head ./site /about

# Make a GET request to the /about page
# This works even with no dev server running, letting your coding agent test things
qip router get ./site /about

# Copy a component to syntax highlight bash code
cp html-code-syntax-highlight-bash.wasm ./site/_recipes/text/markdown/20-html-code-syntax-highlight-bash.wasm

# Generate an archive of the entire site with view source enabled to share your components
qip router warc ./site --view-source

The same components that you use to render the static site can run in the browser via JavaScript. There’s no such thing as a “server component” or “client component”: they are the same component.

Because components are self-contained, maintenance becomes a breeze. Don't worry about needing to update your dependencies every few months so your site still builds. Your site is content plus some .wasm files and a little bit of glue to connect the two. Bitrot be gone!

Cross-platform <canvas> components #

QIP Interactive Components receive keyboard & pointer events and render out pixels.

Use <qip-play> to render them in the browser, or use our SDK to render them in Swift.




See /play for more interactive examples, or /charts for chart-focused components.

Tools without the trackers #

Ever need to generate a favicon or decode base64 and find yourself on a site with more ad banners than inputs? Here are some open source utilities that you can download the .wasm to and run locally.

Want another? Request me to make one.

FAQ #

How is QIP different from WASI?

WASI is useful when a WebAssembly program needs operating-system-like capabilities. QIP is purposefully much narrower. A QIP component gets bytes from the host, transforms them, and returns bytes. It cannot access the filesystem, network, environment, clock, or secrets.

That smaller contract allow components to run easily in browsers, mobile apps, servers, CI, and native hosts. It also makes the attack-surface much narrower.

How is QIP different from React?

React has become the default choice for making web apps and many native apps. Adopting React usually means adopting JavaScript full-stack. QIP wants to be platform and language agnostic: you can write QIP components in anything that compiles to .wasm and you can run .wasm modules pretty much in any modern platform. Because QIP Components are just WebAssembly they work in React (TODO: React QIP documentation page).

How is QIP different from Flutter?

Flutter follows the write-once, run-anywhere philosophy. QIP is also write-once, run-anywhere but is designed to be embedded inside existing apps. You don’t have to port your entire app to QIP and WebAssembly.

This means you can make the most of native tooling and frameworks with proper UI controls and tight integration with the target platform. And then you sprinkle in QIP components where they make sense for their cross-platform or security benefit.

Flutter helps you write one app for many platforms. QIP helps you write one component for many apps.

Learn more #