Packs#
Packs bundle reusable source files and Unity assets into a single ScriptableObject. Drop one onto a JSRunner and its files become importable modules, its objects become accessible from JavaScript.
Quick Example#
A theme pack bundles a stylesheet and some Unity assets:
Pack: "theme"
Files: variables.uss
Objects: logo -> LogoTexture, font -> InterFontIn your app:
import variables from "./@packs/theme/variables.uss"
compileStyleSheet(variables, "theme/variables.uss")
function Header() {
const { logo, font } = __pack("theme")
return (
<View className="header">
<Image image={logo} />
<Label text="My App" style={{ unityFontDefinition: font }} />
</View>
)
}Setup#
- Create: Right-click in the Project window, Create > OneJS > Pack
- Configure: Set a slug (e.g.,
theme), add files and/or objects in the inspector - Add to JSRunner: Drag the asset into the Packs tab; files extract to disk as soon as it is assigned (and automatically on first run and during builds)
Files are extracted to @packs/{slug}/ inside your working directory, along with a .d.ts file for autocomplete. Automatic extraction never overwrites an existing folder; after changing a pack, use the tab's delete and extract buttons to refresh it. Give the pack a Version (e.g. 1.0.0) and bump it whenever its files change: the tab then flags stale extractions as Outdated, and a console warning points at them on the next run.
Accessing Files#
Pack files are regular source files that esbuild can import. Import them by relative path (there is no package alias, so the path is relative to the importing file):
import { ColorWheel } from "./@packs/color-picker/index"
import variables from "./@packs/theme/variables.uss" // plain .uss imports as text
compileStyleSheet(variables, "theme/variables.uss")Accessing Objects#
Object entries are available at runtime as properties on the pack:
const palette = __pack("color-picker").palette // Texture2D
const config = __pack("color-picker").config // ScriptableObjectEach pack auto-generates a .d.ts file, so you get full autocomplete and type checking for object keys.
Namespaces#
Optional namespaces organize packs like npm scoped packages. Set the Namespace field in the inspector:
__pack("color-picker") // no namespace
__pack("@acme/color-picker") // with namespace "acme"Namespaced packs extract to @packs/@{namespace}/{slug}/.
Premade Packs#
You can consume a pack someone else made the same way: add the asset to the Packs tab and import from the extracted folder. The Asset Store version of OneJS ships six under the singtaa namespace: three onejs-ui theme packs and three sample packs. Themes register in one line via onejs:themes; a sample exports components:
import "onejs:themes" // registers every extracted theme pack
import { Inventory } from "./@packs/@singtaa/inventory/inventory"onejs:themes (the themesPlugin() from onejs-unity/esbuild, in scaffolded configs) picks up any extracted module named *Theme.ts, so name your module that way if you author a theme pack and want it auto-registered. See Premade Themes for the full walkthrough.
Builds#
The build processor extracts pack files automatically during Unity builds, overwriting the extracted folders with the pack's current content. Treat extracted files as generated output: keep your own edits in your own source files. Pack objects are injected into the JavaScript context at startup, so __pack() is available immediately when your app runs.
Upgrading From Cartridges#
Packs used to be called UI Cartridges. Nothing you made needs to change:
- Your cartridge assets load as packs, with their files and objects intact.
- A JSRunner made before the rename keeps extracting to
@cartridges/, for new packs too, so the imports your app already has keep resolving. A JSRunner you add now uses@packs/. __cart()still works, as the same function as__pack().- C# code that names
UICartridge,CartridgeUtilsor the other old names still compiles, with an obsolete warning saying what to use instead. A field typedUICartridgekeeps the pack it holds.
One thing does not carry over: ScriptableObject.CreateInstance<UICartridge>() returns null. Create a Pack instead.