Glaze
1 Quick Start
2 Application Lifecycle
run-app
make-api-token
current-api-token
3 Local Server
start-server
stop-server
open-browser
4 Java  Script Bridge
GET
POST
PUT
DELETE
5 Runtime Capabilities
make-capability
allow-permission
scoped-permission
path-permission
command-permission
command-resource
capability-authorized?
current-capability-id
6 Scoped Filesystem
make-filesystem-routes
fs-read-text
fs-write-text!
fs-read-bytes
fs-write-bytes!
fs-read-dir
fs-create-dir!
fs-remove!
fs-copy!
fs-move!
fs-stat
fs-exists?
request-json-body
json-response
api-response
error-response
streaming-response
event-stream-response
define-api-routes
7 Event Push
make-event-bus
bus-broadcast!
bus-subscribe!
bus-unsubscribe!
bus-wait
8 Native Web  View
open-window
open-webview
webview-window-state
webview-set-window-state!
webview-save-state!
webview-restore-state!
webview-supported?
webview-last-error
webview-install-guidance
webview-diagnostic
webview-navigate
webview-close
webview-title
webview-url
webview-capture!
webview-set-title!
webview-set-size!
webview-set-fullscreen!
webview-focus!
webview-set-menu!
webview-closed?
all-webviews
close-all-webviews!
wait-for-webviews
8.1 Startup Dependency Feedback
9 System Integrations
sys-supported?
clipboard-set!
clipboard-get
notify!
open-path
reveal-path
single-instance?
10 System Tray
tray-supported?
make-tray
tray-set-tooltip!
tray-set-icon!
tray-set-menu!
tray-close
11 Security
12 Update Checks
check-update
newer-version?
verify-file-sha256
fetch-update-manifest
select-update
download-update
make-install-plan
make-replace-install-plan
execute-install-plan!
13 Licensing
issue-license
validate-license
license-valid?
machine-id
days-until-expiry
14 File Dialogs
dialog-supported?
pick-file
pick-files
pick-folder
save-file-dialog
15 Deep Links and Launch at Login
ensure-url-scheme!
auto-launch-set!
auto-launch-enabled?
16 Packaging
build-app
17 CLI Commands
9.3.0.10

Glaze🔗ℹ

turinglambdaai

Glaze builds desktop applications with a Racket backend and a Web frontend rendered inside a native OS window. Windows uses WebView2, macOS uses WKWebView, and Linux uses WebKitGTK.

Human-first. Agent-native. Local by design. New projects include an agent instruction contract and native-window verification script. The CLI exposes machine-readable project inspection and runtime diagnostics without changing Glaze’s human-readable workflow.

1 Quick Start🔗ℹ

$ raco pkg install --auto glaze

$ raco glaze init myapp

$ cd myapp

$ raco glaze inspect --json

$ raco glaze doctor --json

$ raco glaze verify

$ racket main.rkt

# or: raco glaze dev

A Glaze application is native-GUI only. If its native WebView cannot start, application startup fails with platform-specific installation or repair guidance. Glaze never substitutes a system-browser tab for the desktop window.

2 Application Lifecycle🔗ℹ

 (require glaze/app) package: glaze

procedure

(run-app [#:public-dir public-dir 
  #:api api 
  #:port port 
  #:title title 
  #:width width 
  #:height height 
  #:events events 
  #:api-token api-token 
  #:capability capability 
  #:on-close on-close 
  #:on-error on-error 
  #:check-update check-update 
  #:current-version current-version 
  #:app-id app-id 
  #:window-state window-state 
  #:on-ready on-ready]) 
 → 
'webview procedure?
  public-dir : (or/c string? path?) = "public"
  api : (listof route?) = '()
  port : (or/c #f exact-nonnegative-integer?) = #f
  title : string? = "Glaze"
  width : exact-positive-integer? = 1024
  height : exact-positive-integer? = 768
  events : (or/c #f event-bus?) = #f
  api-token : (or/c #f string? #t) = #f
  capability : (or/c #f capability?) = #f
  on-close : (-> any) = (lambda () (void))
  on-error : (or/c #f procedure?) = #f
  check-update : (or/c #f string?) = #f
  current-version : string? = "0.0.0"
  app-id : (or/c #f string?) = #f
  window-state : (or/c #f #t path-string?) = #f
  on-ready : procedure? = (lambda (wv url) (void))
The one-call application entry point. It selects a free loopback port unless #:port is supplied, starts the static/API server, opens the native WebView window, invokes on-ready with the webview? handle and clean application URL, and blocks until the window closes.

When the native window closes, the local server is stopped and the procedure returns (values 'webview shutdown). If native WebView startup fails, Glaze first stops the local server and then propagates an actionable startup error. There is intentionally no browser-fallback option.

#:api-token may be a string or #t. With #t, Glaze generates a random capability token and uses a one-time bootstrap URL to set an HttpOnly cookie for the embedded frontend. #:on-error receives API handler failures. #:check-update wires an update manifest into the application lifecycle.

When #:capability is supplied, run-app automatically creates an API token if necessary. Every API route then requires a declared and granted permission; this mode is default-deny.

With #:window-state #t, #:app-id selects a platform config path where Glaze saves outer position, size, and maximized state at close and restores them on the next launch. An explicit path may be supplied instead. Stale geometry is clamped to the current virtual desktop so a disconnected monitor cannot strand the window.

procedure

(make-api-token) → string?

Returns a random 32-hex-character capability token.

parameter

(current-api-token) → string?

(current-api-token token) → void?
  token : string?
Bound by run-app so callbacks can read the active API token; the value is the empty string when API-token protection is disabled.

3 Local Server🔗ℹ

 (require glaze/server) package: glaze
 (require glaze/browser)

procedure

(start-server [#:port port 
  #:public-dir public-dir 
  #:api api 
  #:events events 
  #:api-token api-token 
  #:capability capability 
  #:serve-api-client? serve-api-client?]) 
 → 
exact-nonnegative-integer? procedure?
  port : exact-nonnegative-integer? = 8080
  public-dir : (or/c string? path?) = "public"
  api : (listof route?) = '()
  events : (or/c #f event-bus?) = #f
  api-token : (or/c #f string?) = #f
  capability : (or/c #f capability?) = #f
  serve-api-client? : boolean? = #t
Starts the loopback HTTP server that powers the embedded frontend. Static resources, SPA index fallback, JSON routes, generated API client, and optional SSE event stream share the same origin. The return values are the actual port and a shutdown procedure. start-dev-server remains a compatibility alias for this low-level server primitive; it does not define a browser-based application mode.

The low-level server requires an explicit, non-empty #:api-token whenever #:capability is supplied, keeping runtime authority bound to the embedded WebView rather than an unauthenticated loopback caller.

procedure

(stop-server shutdown-proc) → void?

  shutdown-proc : procedure?
Stops the server.

procedure

(open-browser url) → void?

  url : string?
Explicitly opens an external URL in the user’s default browser. This helper is appropriate for documentation, OAuth, support pages, and similar external resources. run-app, open-window, and open-webview do not use it as a fallback.

4 JavaScript Bridge🔗ℹ

 (require glaze/api) package: glaze
 (require glaze/api-macros)

The embedded frontend calls Racket through ordinary same-origin HTTP requests. This keeps the bridge easy to inspect and test with normal developer tools.

procedure

(GET path    
  handler    
  [#:permission permission    
  #:resource resource]) → route?
  path : string?
  handler : procedure?
  permission : (or/c #f symbol? string?) = #f
  resource : (or/c #f procedure?) = #f

procedure

(POST path    
  handler    
  [#:permission permission    
  #:resource resource]) → route?
  path : string?
  handler : procedure?
  permission : (or/c #f symbol? string?) = #f
  resource : (or/c #f procedure?) = #f

procedure

(PUT path    
  handler    
  [#:permission permission    
  #:resource resource]) → route?
  path : string?
  handler : procedure?
  permission : (or/c #f symbol? string?) = #f
  resource : (or/c #f procedure?) = #f

procedure

(DELETE path    
  handler    
  [#:permission permission    
  #:resource resource]) → route?
  path : string?
  handler : procedure?
  permission : (or/c #f symbol? string?) = #f
  resource : (or/c #f procedure?) = #f

The resource procedure receives the same request and captured path parameters as the route handler. Its result is checked against the active scoped permission before the handler can run. define-api-routes accepts the same #:permission and #:resource options after its route path.

5 Runtime Capabilities🔗ℹ

 (require glaze/capability) package: glaze

procedure

(make-capability id permissions) → capability?

  id : string?
  permissions : list?
Creates a named authority from permission identifiers and scoped permissions.

procedure

(allow-permission id) → any/c

  id : (or/c symbol? string?)
Creates an unscoped permission grant. A bare symbol or string in make-capability has the same meaning.

procedure

(scoped-permission id authorize) → any/c

  id : (or/c symbol? string?)
  authorize : procedure?
Creates a generic resource permission. authorize receives the route resource and must return a true value to authorize the request.

procedure

(path-permission id    
  #:allow allow-roots    
  [#:deny deny-roots]) → any/c
  id : (or/c symbol? string?)
  allow-roots : list?
  deny-roots : list? = '()
Allows resources inside the listed roots except those inside a denied root. Paths are simplified through existing symlinks; deny entries take precedence. The checked resource may be one path or a non-empty list of paths; every path in a list must be authorized.

procedure

(command-permission id    
  #:allow allow-programs    
  [#:deny deny-programs    
  #:arguments arguments-ok?]) → any/c
  id : (or/c symbol? string?)
  allow-programs : list?
  deny-programs : list? = '()
  arguments-ok? : procedure? = (lambda (arguments) #t)
Allows exact executable names or paths and optionally validates their argument list. Deny entries take precedence.

procedure

(command-resource program arguments) → command-resource?

  program : path-string?
  arguments : list?
Constructs the resource returned by a command route’s #:resource procedure.

procedure

(capability-authorized? capability    
  permission    
  [resource]) → boolean?
  capability : capability?
  permission : (or/c symbol? string?)
  resource : any/c = #f
Checks runtime authority without invoking a route.

parameter

(current-capability-id) → (or/c #f string?)

(current-capability-id id) → void?
  id : (or/c #f string?)
Bound to the active capability ID while a protected route handler or resource extractor runs.

6 Scoped Filesystem🔗ℹ

 (require glaze/filesystem) package: glaze

procedure

(make-filesystem-routes [#:prefix prefix]) → (listof route?)

  prefix : string? = "api/fs"
Creates frontend routes for text and binary file I/O, directories, metadata, existence checks, file copy, move, and removal. The routes declare 'fs:read or 'fs:write; use path-permission grants in the active capability. Copy and move expose both paths as one resource, so both source and destination must be in scope.

The default prefix generates client functions such as glaze.api.fsReadText, glaze.api.fsWriteFile, and glaze.api.fsMove. Binary payloads use base64 strings in JSON.

procedure

(fs-read-text path) → string?

  path : path-string?

procedure

(fs-write-text! path text) → void?

  path : path-string?
  text : string?
Writes via a same-directory temporary file and atomic replacement.

procedure

(fs-read-bytes path) → bytes?

  path : path-string?

procedure

(fs-write-bytes! path data) → void?

  path : path-string?
  data : bytes?
Writes via a same-directory temporary file and atomic replacement.

procedure

(fs-read-dir path) → (listof hash?)

  path : path-string?

procedure

(fs-create-dir! path    
  [#:recursive? recursive?]) → void?
  path : path-string?
  recursive? : boolean? = #t

procedure

(fs-remove! path [#:recursive? recursive?]) → void?

  path : path-string?
  recursive? : boolean? = #f

procedure

(fs-copy! source    
  destination    
  [#:replace? replace?]) → void?
  source : path-string?
  destination : path-string?
  replace? : boolean? = #f

procedure

(fs-move! source    
  destination    
  [#:replace? replace?]) → void?
  source : path-string?
  destination : path-string?
  replace? : boolean? = #f

procedure

(fs-stat path) → hash?

  path : path-string?

procedure

(fs-exists? path) → boolean?

  path : path-string?

A route handler receives the web-server request followed by any captured :param path values. Returning a jsexpr produces a JSON 200 response; a full response value may also be returned, including a streaming response (streaming-response / event-stream-response below).

procedure

(request-json-body req) → jsexpr?

  req : request?
Parses a JSON request body. Missing, empty, or malformed input yields an empty hash so route validation can produce a clean client error. JSON object keys in Racket jsexprs are symbols, for example (hash-ref body 'delta).

procedure

(json-response data) → response?

  data : jsexpr?

procedure

(api-response data) → response?

  data : jsexpr?

procedure

(error-response status message) → response?

  status : exact-nonnegative-integer?
  message : string?

procedure

(streaming-response writer    
  [#:mime mime    
  #:headers headers]) → response?
  writer : (-> output-port? any)
  mime : bytes? = #"application/octet-stream"
  headers : (listof header?) = '()
A chunked 200 response. writer runs on the connection thread after the status line and headers go out — the same mechanism as the built-in /glaze/events SSE endpoint. Write to the port and call (flush-output out) after each chunk that should be delivered immediately; returning from the writer ends the response.

A handler that raises before returning still maps to a 500 JSON (nothing is on the wire yet); an exception inside the writer closes the connection mid-stream, so wrap your own errors there if truncation is unacceptable. The typical use is proxying a streaming LLM endpoint — tokens reach the page as they arrive, API keys stay in Racket, and the page never makes a cross-origin call:

(GET "api/llm/chat"
 (lambda (req)
   (streaming-response
    #:mime #"application/x-ndjson"
    (lambda (out)
      (for ([delta (in-llm-deltas (request-json-body req))])
        (displayln (jsexpr->string (hasheq 'delta delta)) out)
        (flush-output out))))))

procedure

(event-stream-response sender    
  [#:headers headers]) → response?
  sender : procedure?
  headers : (listof header?) = '()
The SSE flavor of streaming-response: sender receives a send callback, and each (send name data) emits one

event: name\ndata: <json>

frame and flushes. Consuming with EventSource in the page works out of the box; Cache-Control: no-cache is added automatically.

(GET "api/sse/demo"
 (lambda (req)
   (event-stream-response
    (lambda (send)
      (send 'delta (hasheq 'text "Hel"))
      (send 'delta (hasheq 'text "lo"))
      (send 'done (hasheq 'ok #t))))))

syntax

(define-api-routes id clause ...)

Declares a callable Racket procedure, a validated HTTP route, and a generated JavaScript client entry from one route clause.

(define-api-routes api
  [(POST "api/counter/bump")
   (bump [delta exact-nonnegative-integer? 1])
   (hasheq 'count (add1 delta))])

The generated /glaze/api.js exposes route-specific functions plus glaze.call(...) and glaze.on(...).

7 Event Push🔗ℹ

 (require glaze/events) package: glaze

Glaze uses same-origin Server-Sent Events for backend-to-frontend push.

procedure

(make-event-bus) → event-bus?

Creates a broadcast event bus.

procedure

(bus-broadcast! bus name data) → void?

  bus : event-bus?
  name : (or/c symbol? string?)
  data : jsexpr?
Broadcasts an event without blocking the producer; a full per-subscriber backlog drops that event for the slow subscriber only.

procedure

(bus-subscribe! bus) → async-channel?

  bus : event-bus?

procedure

(bus-unsubscribe! bus channel) → void?

  bus : event-bus?
  channel : async-channel?

procedure

(bus-wait channel [seconds]) → any/c

  channel : async-channel?
  seconds : real? = 10

8 Native WebView🔗ℹ

 (require glaze/webview/main) package: glaze

The native WebView is an application prerequisite, not an optional rendering mode. The backends are WebView2 on Windows, WKWebView on macOS, and WebKitGTK on Linux.

procedure

(open-window url    
  [#:title title    
  #:width width    
  #:height height    
  #:devtools? devtools?    
  #:window-state window-state    
  #:on-close on-close]) → webview?
  url : string?
  title : string? = "Glaze"
  width : exact-positive-integer? = 1024
  height : exact-positive-integer? = 768
  devtools? : boolean? = #f
  window-state : (or/c #f path-string?) = #f
  on-close : (-> any) = (lambda () (void))
Opens a native desktop window and loads url. If the backend or its runtime dependency is unavailable, this procedure raises. Before raising in an interactive desktop process, Glaze also attempts to show an OS-level error dialog so packaged GUI applications without a console still give the user an actionable explanation. CI environments suppress the dialog and retain the exception text in logs.

There is no #:fallback-browser? keyword.

procedure

(open-webview url    
  [#:title title    
  #:width width    
  #:height height    
  #:devtools? devtools?    
  #:window-state window-state    
  #:on-close on-close]) → webview?
  url : string?
  title : string? = "Glaze"
  width : exact-positive-integer? = 1024
  height : exact-positive-integer? = 768
  devtools? : boolean? = #f
  window-state : (or/c #f path-string?) = #f
  on-close : (-> any) = (lambda () (void))
Lower-level synonym of open-window with the same fail-fast contract.

procedure

(webview-window-state webview) → (or/c #f window-state?)

  webview : webview?
Returns the native window’s outer position, size, and maximized state.

procedure

(webview-set-window-state! webview state) → any

  webview : webview?
  state : window-state?
Moves/resizes the native window and restores its maximized state.

procedure

(webview-save-state! webview path) → (or/c #f path?)

  webview : webview?
  path : path-string?

procedure

(webview-restore-state! webview path) → any

  webview : webview?
  path : path-string?
Reads a saved state, clamps it to webview-screen-area, and applies it. Malformed or missing state files are ignored.

procedure

(webview-supported?) → boolean?

Non-throwing capability probe for the current platform backend. Actual window creation remains the authoritative runtime check.

procedure

(webview-last-error) → any/c

Returns the most recent backend probe/startup error.

procedure

(webview-install-guidance) → string?

Returns platform-specific dependency guidance. Windows guidance names the Microsoft Edge WebView2 Evergreen Runtime; Linux guidance names GTK 3 and WebKitGTK packages; macOS explains that WKWebView is part of the OS.

procedure

(webview-diagnostic) → string?

Formats the current error and guidance.

procedure

(webview-navigate wv url) → void?

  wv : webview?
  url : string?

procedure

(webview-close wv) → void?

  wv : webview?

procedure

(webview-title wv) → (or/c #f string?)

  wv : webview?

procedure

(webview-url wv) → (or/c #f string?)

  wv : webview?

procedure

(webview-capture! wv [dest]) → (or/c #f path?)

  wv : webview?
  dest : (or/c #f string? path?) = #f

procedure

(webview-set-title! wv title) → void?

  wv : webview?
  title : string?

procedure

(webview-set-size! wv width height) → void?

  wv : webview?
  width : exact-positive-integer?
  height : exact-positive-integer?

procedure

(webview-set-fullscreen! wv on?) → void?

  wv : webview?
  on? : boolean?

procedure

(webview-focus! wv) → void?

  wv : webview?

procedure

(webview-set-menu! wv menus) → void?

  wv : webview?
  menus : list?

procedure

(webview-closed? wv) → boolean?

  wv : webview?

procedure

(all-webviews) → (listof webview?)

procedure

(close-all-webviews!) → void?

procedure

(wait-for-webviews [timeout-seconds]) → boolean?

  timeout-seconds : (or/c #f real?) = #f

8.1 Startup Dependency Feedback🔗ℹ

When native startup fails, Glaze reports the backend error and remediation. Typical guidance includes:

  • Windows: install or repair Microsoft Edge WebView2 Runtime (Evergreen), with a winget command and Microsoft’s official download page.

  • Debian/Ubuntu: sudo apt install libgtk-3-0 libwebkit2gtk-4.1-0.

  • Fedora: sudo dnf install gtk3 webkit2gtk4.1.

  • Arch: sudo pacman -S gtk3 webkit2gtk-4.1.

  • macOS: WKWebView is built in; use a logged-in graphical session and report the preserved backend error if initialization still fails.

Set environment variable GLAZE_NO_STARTUP_DIALOG to 1 to suppress the interactive error dialog while retaining the exception. Dialogs are also suppressed automatically under common CI environments.

9 System Integrations🔗ℹ

 (require glaze/sys) package: glaze

procedure

(sys-supported?) → boolean?

procedure

(clipboard-set! text) → boolean?

  text : string?

procedure

(clipboard-get) → string?

procedure

(notify! title [body #:subtitle subtitle]) → boolean?

  title : string?
  body : string? = ""
  subtitle : string? = ""

procedure

(open-path path-or-url) → boolean?

  path-or-url : (or/c path? string?)

procedure

(reveal-path path) → boolean?

  path : (or/c path? string?)

procedure

(single-instance? app-id) → boolean?

  app-id : any/c

These helpers are best-effort integrations. Their failure semantics are separate from the WebView startup contract: the WebView is required for the application itself, while an optional integration may report failure without changing the application’s rendering model.

10 System Tray🔗ℹ

 (require glaze/tray) package: glaze

procedure

(tray-supported?) → boolean?

procedure

(make-tray #:icon icon    
  #:tooltip tooltip    
  #:menu menu    
  [#:on-event on-event]) → tray?
  icon : any/c
  tooltip : string?
  menu : list?
  on-event : procedure? = (lambda (e) (void))

procedure

(tray-set-tooltip! tray tooltip) → void?

  tray : tray?
  tooltip : string?

procedure

(tray-set-icon! tray icon) → void?

  tray : tray?
  icon : any/c

procedure

(tray-set-menu! tray menu) → void?

  tray : tray?
  menu : list?

procedure

(tray-close tray) → void?

  tray : tray?

The tray remains an optional capability. If its native backend is unavailable, Glaze may use an inert tray stub; this does not weaken the mandatory native WebView contract for the main window.

11 Security🔗ℹ

The local server binds to loopback and validates Host headers against 127.0.0.1, localhost, and [::1] to reduce DNS rebinding risk.

With #:api-token, API routes and the SSE stream require a capability. run-app opens the native WebView at a one-time bootstrap URL; the server exchanges the token for an HttpOnly cookie and redirects to the clean path. Programmatic clients may use the X-Glaze-Token header.

With #:capability, the server additionally enforces named permissions and resource scopes. Routes without #:permission, routes whose permission is absent, and resources outside a granted scope return 403 before the handler runs. Grant 'glaze:events to authorize the SSE endpoint.

This is defense in depth against casual local callers, not isolation from other processes running as the same OS user.

12 Update Checks🔗ℹ

 (require glaze/update) package: glaze

procedure

(check-update manifest-url 
  [#:current-version current-version]) 
 → (or/c #f hash?)
  manifest-url : string?
  current-version : string? = "0.0.0"
Checks a JSON manifest for a newer version. An optional sha256 field is passed through for artifact verification.

procedure

(newer-version? candidate current) → boolean?

  candidate : string?
  current : string?

procedure

(verify-file-sha256 path expected-hex) → boolean?

  path : (or/c string? path?)
  expected-hex : string?
Returns #t only for a verified digest; #f also covers cases where verification could not be performed.

For installed applications, the signed updater is the preferred path. An update-manifest binds the application id, SemVer version, release channel, minimum supported version, staged rollout percentage, and a set of platform/architecture update-artifact values into one Ed25519-signed payload. Artifact records include a bounded size, SHA-256 digest, installer kind and arguments, and an optional second Ed25519 signature.

procedure

(fetch-update-manifest manifest-url 
  public-key 
  [#:key-id key-id 
  #:maximum-bytes maximum-bytes]) 
 → update-manifest?
  manifest-url : string?
  public-key : path-string?
  key-id : (or/c #f string?) = #f
  maximum-bytes : exact-positive-integer? = (* 1024 1024)
Downloads an HTTPS manifest with a hard byte limit and verifies its signature. If key-id is provided, a valid signature from any other release key is rejected.

procedure

(select-update config manifest) → (or/c #f update-candidate?)

  config : updater-config?
  manifest : update-manifest?
Checks application identity, channel, exact SemVer precedence, minimum version, rollout bucket, platform, and architecture.

procedure

(download-update config    
  candidate    
  destination) → path?
  config : updater-config?
  candidate : update-candidate?
  destination : path-string?
Downloads to a partial file over HTTPS, enforces the configured maximum and signed artifact size, verifies SHA-256 plus the optional artifact signature, then atomically renames the verified file into place.

procedure

(make-install-plan candidate    
  downloaded-path    
  [#:backup-path backup-path]    
  #:install install    
  [#:restart restart    
  #:rollback rollback]) → install-plan?
  candidate : update-candidate?
  downloaded-path : path-string?
  backup-path : (or/c #f path-string?) = #f
  install : procedure?
  restart : procedure? = void
  rollback : procedure? = void

procedure

(make-replace-install-plan candidate 
  downloaded-path 
  target-path 
  #:backup-path backup-path 
  [#:restart restart]) 
 → install-plan?
  candidate : update-candidate?
  downloaded-path : path-string?
  target-path : path-string?
  backup-path : path-string?
  restart : procedure? = void
Creates the atomic portable-artifact strategy, suitable for AppImage-style or self-contained deployments. Native installers use make-install-plan with a platform adapter that owns elevation and process handoff.

procedure

(execute-install-plan! plan) → any

  plan : install-plan?
Runs install and restart. If installation raises and the signed manifest allows rollback, the rollback callback runs before the original exception is raised.

Release automation can validate and sign a payload with raco glaze manifest-sign, then verify the wrapper and pinned key id with raco glaze manifest-verify.

13 Licensing🔗ℹ

 (require glaze/license) package: glaze

Glaze includes an offline RSA-2048/SHA-256 licensing helper backed by the system openssl command.

procedure

(issue-license #:private-key private-key    
  #:product product    
  #:subject subject    
  [#:expiry expiry    
  #:machine-id machine-id    
  #:out output]) → path?
  private-key : path-string?
  product : string?
  subject : string?
  expiry : (or/c #f string?) = #f
  machine-id : (or/c #f string?) = #f
  output : (or/c string? path?) = "app.license"

procedure

(validate-license license-file    
  #:public-key public-key    
  #:product product    
  [#:machine-id machine-id]) → hash?
  license-file : (or/c string? path?)
  public-key : path-string?
  product : string?
  machine-id : string? = (machine-id)

procedure

(license-valid? license-file    
  #:public-key public-key    
  #:product product    
  [#:machine-id machine-id]) → boolean?
  license-file : (or/c string? path?)
  public-key : path-string?
  product : string?
  machine-id : string? = (machine-id)

procedure

(machine-id) → string?

procedure

(days-until-expiry expiry) → exact-integer?

  expiry : string?

14 File Dialogs🔗ℹ

 (require glaze/dialogs) package: glaze

procedure

(dialog-supported?) → boolean?

procedure

(pick-file [#:title title    
  #:directory directory    
  #:filters filters]) → (or/c #f path?)
  title : (or/c #f string?) = #f
  directory : (or/c #f path-string?) = #f
  filters : list? = '()

procedure

(pick-files [#:title title    
  #:directory directory    
  #:filters filters]) → (listof path?)
  title : (or/c #f string?) = #f
  directory : (or/c #f path-string?) = #f
  filters : list? = '()

procedure

(pick-folder [#:title title    
  #:directory directory]) → (or/c #f path?)
  title : (or/c #f string?) = #f
  directory : (or/c #f path-string?) = #f

procedure

(save-file-dialog [#:title title 
  #:default-name default-name 
  #:directory directory 
  #:filters filters]) 
 → (or/c #f path?)
  title : (or/c #f string?) = #f
  default-name : (or/c #f string?) = #f
  directory : (or/c #f path-string?) = #f
  filters : list? = '()

15 Deep Links and Launch at Login🔗ℹ

 (require glaze/deeplink) package: glaze
 (require glaze/autolaunch)

procedure

(ensure-url-scheme! scheme    
  [#:app-name app-name]) → any/c
  scheme : string?
  app-name : string? = scheme
Windows registers a user-scope URL protocol, Linux writes a desktop entry and uses xdg-mime when available, and macOS URL schemes are declared in the bundle at build time.

procedure

(auto-launch-set! name enabled?) → void?

  name : string?
  enabled? : boolean?

procedure

(auto-launch-enabled? name) → any/c

  name : string?

16 Packaging🔗ℹ

 (require glaze/build) package: glaze

procedure

(build-app [#:entry entry    
  #:name name    
  #:version version    
  #:icon icon    
  #:out-dir out-dir    
  #:embed-dlls? embed-dlls?    
  #:installer? installer?    
  #:sign sign    
  #:entitlements entitlements    
  #:no-hardened-runtime? no-hardened-runtime?    
  #:timestamp-url timestamp-url    
  #:notarize-profile notarize-profile    
  #:url-schemes url-schemes]) → path?
  entry : (or/c string? path?) = "main.rkt"
  name : (or/c #f string?) = #f
  version : (or/c #f string?) = #f
  icon : any/c = #f
  out-dir : (or/c string? path?) = "dist"
  embed-dlls? : boolean? = #f
  installer? : boolean? = #f
  sign : (or/c #f string?) = #f
  entitlements : any/c = #f
  no-hardened-runtime? : boolean? = #f
  timestamp-url : (or/c #f string?) = #f
  notarize-profile : (or/c #f string?) = #f
  url-schemes : list? = '()
Builds and distributes the application with raco exe and raco distribute. Windows GUI builds use raco exe --gui, so they may not have a visible console; this is why native WebView startup failures also attempt an OS-level error dialog.

Installer-toolchain absence may degrade an installer request to an archive with a loud warning. That packaging fallback is unrelated to runtime startup: the built application still requires its native WebView.

17 CLI Commands🔗ℹ

raco glaze init <name>                Create a native desktop project

raco glaze dev                        Run the project's native main.rkt

raco glaze build                      Build a distributable / installer

raco glaze keygen [--out <dir>]       Create an RSA keypair for licenses

raco glaze license sign|verify        Sign or verify license files

raco glaze help                       Show help

There is intentionally no browser-mode dev or serve command. Development and production use the same native WebView startup path.