These docs cover 0.2.0-beta.26. Each guide distinguishes supported beta behavior, explicit deployment boundaries, and retained 0.1 compatibility material.

Browse documentationAll guides

Build · package interoperability

Third-party packages

Presolve applications install and import ordinary npm packages. What the compiler needs to understand depends on each use site—not the package name. A CSS plugin can remain Vite-owned, an analytics export can be a terminal Action call, and a returned value can require a dedicated capability contract, all from the same package.

Authority is granted per use

Presolve never marks an entire dependency “framework safe.” TypeScript proves the exact symbol and signature; Presolve admits one documented semantic shape; Vite bundles only the selected browser export.

Choose the integration class

UseAuthorityPresolve meaning
Types, CSS tooling, media, and build pluginsTypeScript or ViteNo component, reactive, capability, or resume identity.
Pure value in an admitted compiler value contractTypeScript + PresolveThe value joins that exact contract; the package gains no blanket meaning.
Result-discarded browser call from an ActionPresolve + TypeScript + ViteExact named import, parameter codecs, completion, cancellation, and resume policy.
Server capability implementationCapability + server adapterThe declared capability owns transport, validation, failure, and lifecycle.
Arbitrary package implementation behaviorThe packageNever assumed to be compiler-understood.

Synchronous package Action

Import one named export and make its call the Action body’s complete behavior. Exact string, number, boolean, and null parameters may be forwarded once and in order.

import { recordEvent } from "@acme/analytics";import { action, Component } from "presolve";export class Checkout extends Component {record = action((category: string,value: number,enabled: boolean,metadata: null,) => {recordEvent(category, value, enabled, metadata);});render() {return <button onClick={() => this.record("checkout", 2, true, null)}>Record checkout</button>;}}

The package declaration must contain the same parameters in the same order. The result is discarded. Objects, arrays, optionals, rest parameters, reordered or duplicated values, default/namespace imports, dynamic imports, computed calls, and additional statements fail closed.

Promise package Action

For cancellable async work, make the handler async, add one final signal: AbortSignal, and make the package call the sole awaited statement. The package must return exact Promise<void>.

import { recordEventAsync } from "@acme/analytics";import { action, Component } from "presolve";export class Search extends Component {record = action(async (query: string, signal: AbortSignal) => {await recordEventAsync(query, signal);});render() {return <button onClick={() => this.record("compiler framework")}>Record search</button>;}}
The caller never passes the signal

The public action() overload removes the injected final signal from the event-call signature. Presolve creates and owns the AbortController at runtime.

Promise lifecycle

Replace previousA newer call aborts the previous invocation for the same component instance and package Action.
TeardownComponent and structural teardown abort pending work before ownership is released.
Navigationpagehide aborts pending work; cancellation is not reported as package failure.
Stale settlementAn older Promise cannot overwrite the completion status of its replacement.
ResumeThe event boundary is restored without replaying a pre-navigation package call.
FailureA thrown or rejected package error is preserved in PSR_PACKAGE_INVOCATION_FAILURE.

Server package capabilities

A package can also provide an executable Node loader or server action. These are not ordinary Action calls: the package must publish an integrity-qualified capability, and application source must select it through the corresponding canonical loader() or defineForm() shape.

Package exportRequired meaning
resource + route_loaderExact (RouteParameters, AbortSignal) -> Promise<RouteLoaderResult>, server/shared boundary, reload resume, typed failure, result codecs, and explicit cache scope.
server_actionExact (FormData, AbortSignal) -> Promise<ServerActionResult>, cold fallback, typed failure, and one JSON or redirect response family.

For these uses, TypeScript proves the named export and exact signature, Presolve proves the component/Form/Resource/route ownership and publishes the closed execution plan, Vite bundles only that export for Node, and the generated host verifies the registry digest before import. Read loaders and server actions for the complete request, cache, cancellation, and bootstrap lifecycle.

What the build publishes

package-invocations.runtime.jsonExact argument codecs, completion, signal injection, concurrency, cancellation, execution, provenance, and restore-without-replay policy.
/presolve.package-invocations.jsVite-generated callable registry containing only authority-proven named exports.
file-routes.manifest.jsonDigest-bound inventory for the invocation artifact and registry.

Who diagnoses what?

QuestionAuthority
Does the module exist, and what symbol/signature does this import mean?TypeScript
Can the selected export bundle for the browser target?Vite
Is the call shape admitted, and are its arguments and lifecycle exact?Presolve
What does the implementation do internally?The package; Presolve does not infer it.
Did an admitted invocation throw or reject?Presolve records failure while retaining the package error.

Historical package declarations

Earlier package declaration forms are documented only in the migration reference. Current applications use the Action forms above; integrations that return values, define codecs, render package components, or cross a server boundary require their own admitted capability product.

Verify an integration

pnpm checkpnpm buildpnpm exec presolve explain app/routes/index.tsxpnpm exec presolve explain --capabilities --format human

Inspect the invocation artifact and registry, test fulfillment, failure, replacement, teardown, and resume in a real browser, and include the exact package/version plus diagnostic when reporting a bug.