Skip to content

Bundled Resources

Put application files that are not compiled into the executable in a resources/ directory: images, templates, JSON, and other data. The CLI copies that directory’s contents into the packaged app. The running app reads them from the resource directory, which does not depend on the launch working directory.

Custom fonts are a separate option. See Fonts.

#The resources directory

my-app/
├── resources/
│   ├── icon.png
│   ├── hero.png
│   └── copy/
│       └── template.txt
├── app.tsx
└── quickgui.config.ts

Each file keeps its path relative to resources/. resources/hero.png is installed as hero.png. resources/copy/template.txt is installed as copy/template.txt. Destination names must not replace reserved names such as fonts, AppIcon.icns, quickgui.json, or the host shared library.

quickgui dev and quickgui build both stage these files. A missing extra path listed in config fails the build. The resources/ directory itself is optional.

#Additional files

Use the resources config option to merge extra files or folders into the same packaged directory. Each extra path is copied under its basename. Do not list the project resources/ folder here; it is included automatically.

import { defineConfig } from "@quickgui/cli";

export default defineConfig({
  language: "typescript",
  name: "My App",
  identifier: "com.example.my-app",
  entry: "app.tsx",
  resources: ["legal/NOTICE.txt", "vendor/data"],
  fonts: ["assets/MyFont.ttf"],
});

legal/NOTICE.txt is installed as NOTICE.txt. vendor/data is installed as data/.

#Install locations

PlatformResource directory
macOS .appContents/Resources
Linux AppDir, AppImage, and .debNext to the executable (usr/bin)
Linux install.sh tarballNext to the executable (~/.local/<package>.app/bin)
Windows installerNext to the executable in $INSTDIR

Join packaged names onto resourceDir at runtime; do not read from the project tree or the current working directory.

#Loading files

Await app.whenReady(), then join the packaged name onto resourceDir:

import { join } from "node:path";
import { app, Window } from "@quickgui/native";
import { Image, createRenderer } from "@quickgui/solid";

await app.whenReady();
const paths = await app.getPaths();
const hero = join(paths!.resourceDir, "hero.png");

new Window({
  title: "My App",
  renderer: createRenderer(() => (
    <Image source={hero} style={{ width: 160, height: 120 }} />
  )),
});

Image accepts that filesystem path. Other files use the same join: read them with Bun.file or readFileSync. Relative image paths are not resolved against the resource directory.

#Fonts

fonts lists OpenType files. The CLI copies them into fonts/ inside the resource directory and registers them before the first window opens.

export default defineConfig({
  language: "typescript",
  name: "My App",
  identifier: "com.example.my-app",
  entry: "app.tsx",
  fonts: ["assets/MyFont.ttf"],
});

Use the font family name in style. Fonts are not a replacement for resources/: an image or JSON file still belongs in that directory or in the extra resources list.