GitHub. Website.

Status: Experimental.

Quick start

StackBlitz demo.

Scaffold your app

If you have an existing Astro app, you can skip this step.

Create a new Astro project with:

$ npm create astro@latest

cd into your project directory and install dependencies with npm install.


whyframe comes in two packages,bthe core library and the framework integration, in this case, Astro.

# Install the core library
$ npm install -D @whyframe/core

# Install the Astro integration
$ npm install -D @whyframe/astro

Since iframes are dynamic, you need a UI framework setup for Astro, e.g. Svelte, Vue, Solid, etc. This will render HTML within the iframe using the framework.

Since Astro is also UI framework-agnostic, you can also install other integrations like @whyframe/svelte so it runs on Svelte files too! The difference between it and @whyframe/astro is that @whyframe/svelte scans .svelte files only, and @whyframe/astro scans .astro files only.


whyframe works on the bundler level, so the packages are simply Vite plugins. You can initialize these plugins in your astro.config.mjs:

import { defineConfig } from 'astro/config'
import svelte from '@astrojs/svelte'
import { whyframe } from '@whyframe/core'
import { whyframeAstro } from '@whyframe/astro'

export default defineConfig({
  integrations: [svelte()],
  vite: {
    plugins: [
      // Initialize core plugin
        defaultSrc: '/frames/default' // provide our own html

      // Initialize Astro integration plugin
        // Render `iframe`s as Svelte components by default,
        // can be changed via `data-why="vue"`
        defaultFramework: 'svelte'

As whyframe’s default HTML doesn’t work in Astro, a custom HTML source is required. See HTML source for more information.

To setup /frames/default, or in other words http://localhost:3000/frames/default, create a src/pages/frames/default.astro file:

<!doctype html>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <div id="app"></div>
      // Special api to mount the app
      import { createApp } from 'whyframe:app'
      // Mount the app to `<div id="app"></div>`

And done! You can also add more code and styles to src/pages/frames/default.astro if you prefer.


In src/pages/index.astro (or any other page), you can create an iframe like below:

<iframe data-why>
  Hello world!

Also, make sure the HTML inside the iframe is strictly the UI framework syntax. This is because Astro code is exclusively server-side and can’t be rendered dynamically in the browser. For example, if using Vue:

<iframe data-why="vue">
  <p @click="something">Hello world!</p>

Start your app with npm run dev and watch Hello world! rendered within the iframe as-is!

Check out Features for more things you can do with whyframe.