gridland
Guides

Custom Bundler

Use Gridland with webpack, Rollup, or other bundlers

If you're not using Vite or Next.js, you can configure your bundler manually. Gridland provides first-party plugins for Vite and Next.js — use those if possible.

What the plugins do

The Vite and Next.js plugins handle two things your bundler must also do:

  1. Resolve the opentui engine — Point @opentui/core, @opentui/react, and @opentui/ui to their source entry points (only needed when building from the monorepo with the opentui submodule)
  2. Stub native modules — FFI bindings (bun:ffi, bun-ffi-structs), tree-sitter, and other native modules need no-op browser stubs

Webpack example

Install

npm install @gridland/web

Configure aliases

Add webpack aliases for the native module stubs bundled with @gridland/web:

webpack.config.js
const path = require("path")

const gridlandWeb = path.dirname(require.resolve("@gridland/web/package.json"))
const shim = (p) => path.resolve(gridlandWeb, p)

module.exports = {
  resolve: {
    alias: {
      // FFI stubs
      "bun:ffi": shim("src/shims/bun-ffi.ts"),
      "bun-ffi-structs": shim("src/shims/bun-ffi-structs.ts"),
      bun: shim("src/shims/bun-ffi.ts"),

      // Events shim
      events$: shim("src/shims/events-shim.ts"),

      // Tree-sitter stubs
      "tree-sitter-styled-text": shim("src/shims/tree-sitter-styled-text-stub.ts"),
      "web-tree-sitter": shim("src/shims/tree-sitter-stub.ts"),
      "hast-styled-text": shim("src/shims/hast-stub.ts"),
    },
  },
  experiments: {
    topLevelAwait: true,
  },
}

Use it

App.tsx
import { TUI } from "@gridland/web"

export default function App() {
  return (
    <TUI style={{ width: "100vw", height: "100vh" }}>
      <box border borderStyle="rounded" padding={1}>
        <text fg="#a3be8c">Hello from Gridland!</text>
      </box>
    </TUI>
  )
}

The full list of aliases and shims can be found in the Vite plugin source and Next.js plugin source.