Nexanexa
Step 10

Third-party libraries and other frameworks

Bootstrap, PrimeVue, a Chart.js graph, a Phaser game, or living alongside a whole Quasar, Vue, React or Angular app? Nexa doesn't replace any of that — it knows how to coexist with all of it, through a different mechanism depending on how "alive" the library is.

Third-party CSS: a plain <link>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">

Bootstrap, Tailwind via CDN, PrimeVue/PrimeReact's CSS — Nexa never processes or understands that CSS, so no special step is needed. A <link rel="stylesheet"> in src/layout.tsx (site-wide) or in a single page is enough.

JS with a global (UMD) build: a plain <script>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

function renderChart() {
    new Chart(document.getElementById("chart"), {
        type: "bar",
        data: { labels: ["Jan", "Feb"], datasets: [{ data: [10, 20] }] }
    });
}

Bootstrap JS, Chart.js, and in general anything you can load as a classic <script> (not type="module") leaves a global variable (bootstrap, Chart, ...). Since a Nexa chunk copies the handler verbatim, you can use that global directly in an onClick — no need to declare anything in nexa.toml.

Pure ES module libraries: the same [imports] as platform/stripe

# nexa.toml
[imports]
confetti = "https://esm.sh/canvas-confetti"

If the library is only distributed as an ES module (no global build), use [imports] — the same mechanism platform and stripe already use. The chunk detects <name>. in the handler and prepends the import; the import map in <head> resolves the specifier to the real URL.

Full engines and frameworks: as an island

<div data-nexa-island="game" data-nexa-strategy="visible">
    <p>Loading game…</p>
</div>

// src/islands/game.island.ts — Phaser loaded as a global <script>
export default function mount(el) {
    const game = new Phaser.Game({ parent: el, width: 800, height: 600 });
    return () => game.destroy(true);
}

For something with its own lifecycle — a Phaser game loop, or a stateful Vue/Quasar/React/Angular component tree — the answer is an island, not a loose [imports] in a handler. Your Quasar app compiles with ITS OWN build (Vite, same as always); Nexa never reads your .vue files or your React .tsx, it just serves the final bundle like any other JS. Important: even though Nexa's syntax looks like React (JSX, export default function), a Nexa page is NOT a React component — it compiles to static HTML once, with no VDOM, no hooks, no re-render. useState/useEffect don't work there; if you genuinely need that, it belongs inside an island using real React.