---
title: filedom
description: "The main entry point: roots, the startSession lifecycle, the asset-authoring toolkit, and shared types."
---

The default entry point, `filedom`, has everything needed to build desktop apps
and games. [Components](/docs/reference/components) and [hooks](/docs/reference/hooks)
have their own pages. This page covers roots and the session lifecycle, asset
authoring, and the shared types. Native and filesystem operations are in
[`filedom/system`](/docs/reference/system).

## Roots

```tsx
import { createRoot, desktopContainer, render } from 'filedom';
import type { RendererRoot, VirtualDesktop } from 'filedom';
```

- `createRoot(container?)` returns a `RendererRoot`. Call it with no argument to
  render to the real `~/Desktop`, with a path string to target another
  directory, or with a full `VirtualDesktop` container. Only one root or session
  can be active at a time; creating a second one throws before it touches the
  desktop.
- `desktopContainer(path?)` builds the standard `VirtualDesktop` container for a
  path (default `~/Desktop`), the same object `createRoot()` uses.

A `RendererRoot` has these members:

- `render(element, callback?)` renders or updates the tree.
- `await dispose()` unmounts the tree, deletes the files it rendered, waits for
  queued native work, and restores any wallpaper or view options the tree
  changed. Repeated calls share one result, and cleanup failures reject it.
- `unmount(callback?)` starts `dispose()` and calls `callback` when it finishes.
- `prepared`, `desktopPrepared`, `poolPrepared`, and `ready` are promises for
  the startup stages: the boot sweep of a previous run's leftover files, the
  initial wallpaper and view options, a warm Stage pool, and the initial
  presentation.

## startSession

Use `startSession` for a full desktop takeover instead of wiring the steps
yourself:

```tsx
import { startSession } from 'filedom';

const session = await startSession(<MyGame />, {
  dialog: { title: 'My Game', message: 'Arrows move · Q quits' },
});
// session.exit(): unmount, clean up, restore the desktop, exit the process.
```

In order, `startSession`:

1. reserves the desktop, rejecting a second root or session before any change;
2. installs `SIGINT`, `SIGTERM`, and `SIGHUP` handlers that run the cleanup;
3. autohides the Dock and menu bar, recording the user's own settings first;
4. shows the optional controls dialog;
5. hides the user's existing Desktop items in place (see below);
6. creates the root, waits for calibrated metrics, renders, and shows the
   desktop.

With the default `clearDesktop: true`, the Desktop items are hidden by setting
the macOS hidden flag on them. Their files are not moved, renamed, or deleted,
and their icon positions survive. A journal at `~/.filedom-desktop-stash`
records each item's identity before any flag changes. A journal left by a
crashed run is recovered on the next start, and ambiguous recovery stops for
inspection. On exit, the flag is cleared only where the file is still the same
inode and still hidden, so items the user had already hidden stay hidden.
Finder's "show all files" preference is turned off for the session with
Cmd+Shift+`.` (this needs Accessibility) and restored afterwards. See
[Desktop stash & restore](/docs/reference/system#desktop-stash--restore).

`startSession` returns a `DesktopSession`:

- `root`: the `RendererRoot`.
- `ready`: resolves when the initial presentation is complete and rejects on a
  startup failure.
- `close()`: restores everything without exiting the process. It removes the
  game's files, runs your `cleanup`, reveals the Desktop items, and puts the
  Dock and menu bar back. Repeated calls share one result. Every step is
  attempted, and failures reject together as an `AggregateError`. After a failed
  close the session keeps ownership of the desktop, so restart the process
  instead of reusing it.
- `exit()`: runs `close()`, then exits the process.

A startup failure rolls back through the same cleanup, so a `cleanup` hook must
tolerate a partial start.

`StartSessionOptions`:

- `dialog`: `{ title, message }` for the controls dialog.
- `clearDesktop`: hide the user's Desktop items for the session (default
  `true`).
- `cleanup`: an async hook that runs during close or startup rollback, before
  hidden items are revealed.
- `desktopPath`: the directory to render into (default `~/Desktop`).
- `feedback`: a lifecycle status display, or `false` for none.

`cleanup` is rarely needed. The library owns every filename a
[`Stage`](/docs/reference/components/stage) mints: unmount removes the files it
rendered, and leftovers from a run that exited uncleanly are swept at the next
boot. Use `cleanup` for desktop files your own code created outside the
reconciler.

Under Finder Mode (`FINDER_MODE_SUPERVISED`), the signed app hides and restores
the Desktop itself, using its own journal at `~/.finder-mode-stash`, and shows
its own controls UI. The session skips its own hiding and the dialog.

## Components, hooks, stages

Everything on these pages is exported from `filedom`:

- [Wallpaper](/docs/reference/components/wallpaper) and
  [VirtualTreeProvider](/docs/reference/components/virtual-tree-provider)
- [Stage & Sprite](/docs/reference/components/stage): `StageProvider`, `Stage`,
  `Sprite`, and the park hooks (`useStagePark`, `useStageSession`,
  `canonicalPark`)
- [Text & scores](/docs/reference/components/text): `Score` and `Text`, the single
  text component, which `textTiles` feeds
- [Overlay & controls](/docs/reference/components/overlay): `useGameControls`,
  `useGameOverlay`, `GameOverlay`
- [Layout](/docs/reference/components/layout): `fitIconSize`, `centerBoard`,
  `createGrid`, `distribute`
- [Hooks](/docs/reference/hooks): metrics, view options, input, game loop

## Asset-authoring toolkit

Icons are pre-baked PNGs, because the [rendering model](/docs/learn/rendering-model)
rules out changing them at runtime, so every game has an asset build step. The
toolkit makes one manifest the source of truth for both the build and the
runtime:

```tsx
import path from 'node:path';
import { defineAssets, solid, type IconSpec } from 'filedom';

const ball: IconSpec = (c) => c.circle({ r: c.canvas * 0.4, fill: '#f5f5f4' });

export const assets = defineAssets({
  iconDir: path.resolve(import.meta.dirname, 'assets/icons'),
  icons: {
    ball,
    paddle: solid('#38bdf8'),
  },
});

// build step: `assets.build()` renders SVG → PNG into iconDir (sync)
// runtime:    `assets.icon('ball')` → IconDescriptor, `assets.iconPath('ball')`
```

An icon entry is either an `IconSpec` draw function, `(c: DrawContext) =>
svg-fragment`, or `{ svg: () => string, size? }` for a complete SVG document.
The manifest has `icon(key)`, `iconPath(key)`, `build()`, and `iconKeys`. Keys
are typed, so a misspelled asset name fails at compile time. `textStrip`
returns `{ count, tiles }`; spread its `tiles` into `icons` under your own keys,
one per tile.

All of these are exported from `filedom`:

- Manifest: `defineAssets`, `DrawContext`, `solid`, `playButton`, `lighten`,
  `ICON_CANVAS_SIZE`, `ICON_PAINTED_FRACTION`, `tileStride`.
- Typography: `textTiles` (lines and a shape in, a laid-out block for
  [Text](/docs/reference/components/text) out), `stripTiles` (the same layout for
  tiles you baked yourself), `renderText`, `labelIcon`, `textStrip` (one kerned
  line sliced across several tiles), `textCells` (the dense monospace grid),
  `textTileStride`, `loadFont`, `defaultFontFile`, and `RETRO_FONT_FILE` (the
  shared arcade face).
- Glyphs and digits: `glyphIcon`, `boxedGlyphIcon` (the banner sets),
  `scoreDigitIcon`, `resolveDigitIcon`.
- Rasterizing: `rasterizeSvg`, `sliceSvgGrid`, `bakeIconPng`, and
  `bakeIconPngSync`. The bake functions cache by content hash across runs.

## Shared types

The entry point re-exports every type from the types package, including
`VirtualDesktop`, `VirtualFile`, `VirtualFolder`, `VirtualNodeType`,
`IconDescriptor` and its `IconSource` variants, `SystemMetrics`,
`ViewOptionsProps`, `WallpaperProps`, and `PositionTransition`. The `IconColor`
and `ViewOptionsArrangement` enums are exported as values.

## Related

- [`filedom/system`](/docs/reference/system): the native and filesystem bridge
- [`filedom/sound`](/docs/reference/sound): game audio
- [Architecture](/docs/reference/architecture): how the packages fit together
