On this pageOverview
Crash View
When Foldkit hits an unrecoverable error during update, view, or Command execution, it stops all processing and renders a fallback UI. This is not error handling — there is no recovery from this state. The runtime is dead.
By default, Foldkit shows a built-in crash screen with the error message and a reload button. Pass a crash.view function to makeElement or makeApplication to customize it. It receives a CrashContext containing the error, the model at the time of the crash, and the message being processed:
import { Runtime } from 'foldkit'
import { Html, html } from 'foldkit/html'
const crashView = ({ error }: Runtime.CrashContext<Model, Message>): Html => {
const { div, h1, p, button, Class, Attribute } = html<never>()
return div(
[Class('min-h-screen flex items-center justify-center bg-red-50 p-8')],
[
div(
[
Class(
'max-w-md w-full bg-cream rounded-lg border border-red-200 p-8 text-center',
),
],
[
h1(
[Class('text-red-600 text-2xl font-semibold mb-4')],
['Something went wrong'],
),
p([Class('text-gray-700 mb-6')], [error.message]),
button(
[
Class(
'bg-red-600 text-white px-6 py-2.5 rounded-md text-sm font-normal cursor-pointer',
),
Attribute('onclick', 'location.reload()'),
],
['Reload'],
),
],
),
],
)
}
const element = Runtime.makeElement({
Model,
init,
update,
view,
crash: { view: crashView },
container: document.getElementById('root')!,
})
Runtime.run(element)Call html<never>() with never as the type parameter. Since the runtime has stopped, no Messages will ever be dispatched — never makes this explicit and prevents event handlers like OnClick from being used.
Foldkit’s event handlers like OnClick work by dispatching Messages to the runtime. Since the runtime has stopped, those handlers are silently ignored. For interactivity, like a reload button, use Attribute('onclick', 'location.reload()'). This sets a raw DOM event handler directly on the element, bypassing Foldkit’s dispatch system entirely.
Only in crash.view
In a normal Foldkit app, always use OnClick with Messages — never raw DOM event attributes. crash.view is the one exception because the runtime is no longer running.
If your custom crash.view itself throws an error, Foldkit catches it and falls back to the default crash screen showing both the original error and the crash.view error.
Use crash.report to run side effects when the app crashes — for example, sending the error to Sentry or another logging service. It receives the same CrashContext as crash.view, giving you access to the error, Model, and Message:
import { Runtime } from 'foldkit'
const element = Runtime.makeElement({
Model,
init,
update,
view,
crash: {
report: ({ error, model, message }) => {
Sentry.captureException(error, {
extra: { model, message },
})
},
},
container: document.getElementById('root')!,
})
Runtime.run(element)crash.report is a synchronous callback. The runtime is dead at this point, so there is no Effect runtime to schedule work on. If you need async behavior (like flushing a logging buffer), fire it from within the callback yourself.
crash.report runs before crash.view renders. If crash.report throws, Foldkit catches the error, logs it to the console, and continues rendering the crash view.
See the crash-view example for a working demonstration.
The next two pages cover how Foldkit warns you about slow views during development and how to memoize expensive subtrees.