Perch
Lua APIApps

Apps

perch.apps: the recently used and most used programs with their icons, the foreground application, launching, and the apps types. Scope apps.

2 min readUpdated Sep 9, 2026

Perch tracks which windows the user focuses and keeps two short lists: recent, and most used today. The apps scope reads them and launches from them; it never executes arbitrary paths.

ScopeInstalls
appsperch.apps.read(), perch.apps.launch(entry), perch.apps.focused(), perch.apps.on_focus_change, perch.apps.configure(options)

The apps dock with recent programs, and the shortcuts dock

perch.apps.read

perch.apps.read(): app_lists_t

{ recent, top }, each up to 6 entries. Synchronous. The lists have no signal; poll while your page is visible.

perch.apps.launch

perch.apps.launch(entry: app_entry_t): ()

Launches an entry that came from read(). A table that did not raises perch.apps.launch(entry): pass an entry from perch.apps.read(). In a repeater the tap’s ctx.index picks the entry out of the last read:

--!strict
type app_refs_t = { icon: field_ref_t<string>, name: field_ref_t<string> }
local recent: { app_entry_t } = {}

local function launch(ctx: input_context_t)
  local entry = recent[ctx.index or 1]
  if entry then perch.apps.launch(entry) end
end

-- in the tree
ui.list { items = f.apps, max = 5, gap = 8,
  item = function(it: app_refs_t): node_t
    return ui.column { w = 66, on_click = launch,
      ui.image { src = it.icon, w = 42, h = 42, hover = ui.hover.lift },
      ui.text { text = it.name, size = 12 },
    }
  end }

-- in logic
local function refresh()
  recent = perch.apps.read().recent
  local rows = {}
  for i, e in ipairs(recent) do rows[i] = { icon = e.icon or "", name = e.name } end
  dock:push({ apps = rows })
end

perch.apps.focused

perch.apps.focused(): focused_app_t?
perch.apps.on_focus_change: signal_t<focused_app_t>

The application in the foreground right now, or nil when Perch cannot tell; and the signal that fires whenever it changes, regardless of the tracking option. ref is the launch reference perch.open.app accepts.

perch.apps.configure

perch.apps.configure(options: apps_options_t): ()

How the builtin Apps package applies its settings page. tracking = false stops tracking and wipes the store; exclude lists programs to leave out, as settings.launch values, matched by executable name.

Types

export type app_entry_t = { name: string, sub: string?, icon: string?, ref: string }
export type app_lists_t = { recent: { app_entry_t }, top: { app_entry_t } }
FieldMeaning
namethe program’s display name
subrecent: "just now", "3m ago", "2h ago"; top: "14m today", "1.5h today"; "" under a minute
icona file:// URL of the extracted icon, or ""
refthe launch reference
export type focused_app_t = { app_id: string, name: string, ref: string }
export type apps_options_t = { tracking: boolean?, exclude: { { target: launch_target_t? } }? }

The foreground application, and the argument of configure.

esc
Type to search
navigate open