Library Template
The Library project type scaffolds a publishable component package. It ships source .jsx (or .tsx) from index.js — consumer apps compile those files through their own otfw toolchain. There is no separate build step in the library itself.
Scaffold
bun create @opentf/web my-lib
Choose Library at the project-type prompt, then pick JavaScript or TypeScript and a styling solution. Dependencies are installed automatically.
Project layout
my-lib/ ├─ index.js # package entry — re-exports components ├─ src/ │ └─ Counter.jsx # sample component ├─ tests/ │ └─ counter.test.js ├─ test-setup.js # wires otfwc + @opentf/web-test/setup ├─ bunfig.toml # preloads test-setup.js └─ package.json
The entry file re-exports components:
export { default as Counter } from "./src/Counter.jsx";
Sample component
export default function Counter({ initial = 0 }) { let count = $state(initial); return ( <button type="button" onclick={() => count++} data-testid="counter"> Count {count} </button> ); }
Testing
The template includes @opentf/web-test and a test-setup.js preload that points OTFWC_BIN at @opentf/web-compiler before loading the web-test setup module:
import { otfwcPath } from "@opentf/web-compiler"; process.env.OTFWC_BIN ??= otfwcPath(); await import("@opentf/web-test/setup");
Run tests
bun test
Publish
Bump version in package.json, then publish to npm:
npm publish
The files field includes index.js and src/ — consumers receive source, not a pre-built bundle.
Consuming in an app
Install the package in an OTF Web app and import components normally:
bun add my-lib
import { Counter } from "my-lib"; export default function Home() { return <Counter initial={5} />; }
The app's otfw dev server and build pipeline compile the library's .jsx sources just like local components. @opentf/web is a peer dependency of the library — the host app provides the runtime.
Choose TypeScript at the scaffold prompt to get .tsx sources, index.ts, and a tsconfig.json. The consumption model is the same — apps compile the shipped sources.
Related
web-test setup — how the test preload works.
Project structure — App and Docs layouts.