Overview
Yes, you can use the npm package you already know, and you import it exactly the way you already do.
import express, { type Request, type Response } from 'express';import { readFileSync } from 'node:fs';
const html = readFileSync('index.html', 'utf-8');
const app = express();app.get('/', (_req: Request, res: Response) => res.type('html').send(html));app.listen(8080);That file builds and runs on all four runtimes, and nothing in it mentions @gjsify. What changes is what the imports resolve to. An --app gjs build rewrites node:fs to @gjsify/fs, backed by Gio.File, and every node:* import inside express and its dependencies goes the same way. An --app node build leaves them alone, because Node, Bun and Deno ship those builtins themselves. How It Works has the details.
Install a package from npm
Section titled “Install a package from npm”Install it like any other dependency. Each installer writes the module layout its own runtime resolves against, so use the one your project is set up for.
gjsify install expressnpm install expressbun add expressdeno add npm:expressYou never add @gjsify/fs, @gjsify/http or any other polyfill by hand. @gjsify/cli depends on two umbrella packages, @gjsify/node-polyfills and @gjsify/web-polyfills. Once the CLI is a devDependency of your project, and every scaffold from gjsify create has it, the whole polyfill set is already resolvable. Name an umbrella yourself only if you build without @gjsify/cli in your dependency tree.
Node.js builtins and Web APIs
Section titled “Node.js builtins and Web APIs”Import builtins with the node: prefix, or the bare form (import fs from 'fs') that older dependencies use. Node.js Modules lists each one and what backs it. fetch, WebSocket, crypto.subtle and ReadableStream are globals, not imports, and Web APIs lists everything available that way.
When you do write @gjsify/... in an import
Section titled “When you do write @gjsify/... in an import”These are the things that have no standard bare specifier:
- GTK bridge widgets.
@gjsify/canvas2d,@gjsify/webgl,@gjsify/videoand@gjsify/iframeexport widget classes you mount into a GTK tree. See DOM & Graphics. - The Adwaita design system on the web.
@gjsify/adwaita-webgives you Adwaita as Web Components for--app browserbuilds. See the Adwaita gallery. - The native app shell.
@gjsify/adwaita-appwraps theAdw.Applicationboilerplate. See Build a native Adwaita app. - The renderer host.
@gjsify/gtk-hostis the element model the Solid, Vue and React renderers bind to, so you describe a GTK window instead of assembling it. Its/stylesubpath answers a utility class or a style object with GTK CSS, a widget property, or an intent. See UI Frameworks and Styling on GTK. - React Native’s vocabulary.
@gjsify/react-nativeis the package a bundler aliasesreact-nativeto:<View>,<Text>,<Pressable>over the same host, with a support table that gives every name it does not implement a status and a reason. See React Native.
gjsify install @gjsify/canvas2d @gjsify/adwaita-appnpm install @gjsify/canvas2d @gjsify/adwaita-appbun add @gjsify/canvas2d @gjsify/adwaita-appdeno add npm:@gjsify/canvas2d npm:@gjsify/adwaita-appWhat is implemented
Section titled “What is implemented”| Category | Packages | What you get |
|---|---|---|
| Node.js Modules | one per builtin, plus meta packages that pull a whole set in | fs, net, http, crypto, stream, events, sqlite, ws and more |
| Web APIs | one per standard, plus meta packages and the native Vala bridges some opt into | fetch, XMLHttpRequest, WebSocket, WebRTC, WebAudio, Streams, DOMParser, MessageChannel, WebAssembly and more |
| DOM & Graphics | the DOM element model, plus one bridge per GTK-backed element | Canvas 2D, WebGL, DOM elements, and the GTK-backed Canvas / WebGL / Video / IFrame widgets |
| Framework | renderer host, React Native layer, app shell plus tooling | @gjsify/gtk-host and its style partition, @gjsify/react-native, @gjsify/adwaita-app, storybook, devtools |
| Adwaita for the browser | the widget set, its headless core, and the assets and storybook renderer beside them | @gjsify/adwaita-web, @gjsify/adwaita-core, @gjsify/adwaita-fonts, @gjsify/adwaita-icons, @gjsify/adwaita-storybook |
| Reverse bridge | 1 | @gjsify/node-gi, GObject-Introspection on Node.js, Bun and Deno |
| Forward bridge | 1 | @gjsify/napi, native Node.js N-API .node addons in GJS |
Coverage says how much of each row is implemented, module by module, rendered from generated data. No percentage is repeated here by hand: a rendered list cannot disagree with itself, and a number typed beside it on another page has nothing holding it.
DOM ↔ GTK Bridges
Standard DOM elements, rendered natively
App code uses standard HTML elements. Each bridge translates the DOM lifecycle to a GTK widget — Cairo for 2D, OpenGL via libepoxy for WebGL, GStreamer for video, WebKit for iframes.
HTMLCanvasElement (2D) Gtk.DrawingArea @gjsify/canvas2d Cairo + PangoCairo
HTMLCanvasElement (WebGL/WebGL2) Gtk.GLArea @gjsify/webgl Vala/gwebgl + libepoxy
HTMLIFrameElement WebKit.WebView @gjsify/iframe WebKit 6.0
HTMLVideoElement Gtk.Picture @gjsify/video GStreamer + gtk4paintablesink
Native Vala bridges
@gjsify/terminal-native Posix.isatty + ioctl TIOCGWINSZ + termios for @gjsify/tty
@gjsify/sab-native Cross-process shared memory + futex atomics for @gjsify/worker_threads
@gjsify/tls-native Direct OpenSSL access for @gjsify/tls
@gjsify/http-soup-bridge Native Soup integration helpers for @gjsify/http
@gjsify/http2-native nghttp2 bridge for h2c, push streams, flow control
@gjsify/webrtc-native GLib.Idle signal marshalling for webrtcbin's streaming-thread callbacks
Will my dependency work?
Section titled “Will my dependency work?”It depends on what it reaches for, and two checks tell you before you try.
- The module list. If your dependency only touches modules marked Full on the Node.js and Web APIs pages, it will almost certainly run.
- The integration suites. Coverage lists the real npm packages whose own test suites run unmodified against
@gjsify/*:axios,socket.io,yargs,execa,fast-glob,cosmiconfig,webtorrent,acornand more. Express, three.js and Excalibur.js run as full showcases.
If a build fails on a missing global, the error names the identifier and How It Works shows the one-flag fix.
Where to go next
Section titled “Where to go next”- Node.js Modules, every builtin and what backs it
- Web APIs, the standards that work as globals
- DOM & Graphics, canvas, WebGL, video and iframes inside GTK windows
- Versioning, how to upgrade
@gjsify/*safely - Runtimes, the same source on GJS, Node.js, Bun, Deno, the browser and mobile