Docs
Upgrading
Move between Proa versions and find what broke.
Proa is pre-1.0. Minor versions carry breaking changes. Each is listed in CHANGELOG.md, with larger ones under a Breaking marker and a guide under docs/migrations/ (0.3 standalone, shared WebContext).
Read the changelog first, then upgrade one minor version at a time:
cargo update -p proa
cargo proa check
cargo proa check runs the template lints and the RSJS linker together, which is where most upgrade breakage surfaces. A plain cargo check will miss link-time errors.
Upgrading to 0.4
Applications can replace direct rendering and framework dependencies with the
proa facade:
[dependencies]
proa = { version = "0.4", features = ["axum"] }
Import common types and macros from proa::, loaders from proa::stream, and
Axum integration from proa::axum. Add actions or react only when needed.
RSJS and build-time font dependencies retain their own package versions.
Direct implementation-crate dependencies remain supported for advanced uses.
Managed metadata uses render_head, explicit Page/Layout roles, and a head
outlet. Markdown macros use one string body, and content_part! wrappers are
removed. Review which outgoing URLs need the application mount and use
cx.url(path) for those. See metadata,
Markdown, and rendering responses.
Upgrading to 0.3
0.3 was a consolidation release. Six surfaces were removed and one buffer became the standard.
| Change | What to do |
|---|---|
| Standard render buffer | Replace bespoke writers with RenderBuffer. See WriteBuf |
| Component-tree ownership moved | Components take ownership of children rather than borrowing |
| Native-mobile surface removed | No replacement. The crate no longer targets it |
Runtime-template and Vm* surface removed | Templates are compile-time only. Move dynamic templates to data-driven components |
| Documentation-build adapters removed | Use proa_docs_build. See Proa Docs |
| Product-specific route codegen removed | Author routes directly. See Routes and layouts |
Upgrading past 0.3
Breaking changes since 0.3 affect how components are authored and linked, how fonts are declared, and how Markdown components receive their context:
#[proa_component]is gone, along with the inherent#[rsjs(component)]shorthand and RSJSasync fn rendersugar. AuthorWebRenderSyncor the canonicalWebRendersignature directly, then apply#[rsjs(component)]for composition or#[rsjs(component, client)]when the component originates browser work. See HTML rendering.- Component-level
clients(...)allowlists are gone. A reachable call to a#[rsjs::client]helper now creates a linker edge automatically.#[rsjs::client_module]remains as optional grouping. See Client helpers. - Deployable RSJS binaries require the linked
cargo proapipeline.cargo checkand rust-analyzer still give provisional type checking, butcargo buildon an RSJS application now fails at link time with an actionable diagnostic instead of quietly producing a provisional binary. cargo proa font add/font removeandproa-fonts.tomlare gone. Declare fonts in code withgoogle_font!/local_font!; abuild.rscollector vendors them and recordsproa-fonts.lock.cargo proa font syncruns the same collector outside a build. See Fonts.MdContextis gone.MdRenderSyncandMdRendernow take the sameWebContext<L, B>as the HTML traits, with the loader first and no lifetime parameters, and Markdown helpers are namedmd_*/write_md_*. See Markdown and the migration guide.RouteResponseis an opaque deferred-render plan andLayoutcarries metadata only; the crate isproa_framework_axum. See Responses and the changelog for the smaller entries (event-handler parameters,RenderOptions,mdx!, client IR v3).- Managed metadata uses component roles and head hooks. Select one
ROLE = PAGE, mark ancestor metadata layouts asLAYOUT, and place one{cx.head()}outlet in the document. Async hooks use nativeasync fn render_head(...) -> Result<(), WriteError>. The formerhead()inspection getter ishead_state(); mutations go through the checkedhead_mut()writer. Enable managed mode withFrameworkBuilder::with_head(...), or use.without_head()while migrating a manual document. See Metadata. FrameworkBuilder::new()andRouteContextLayer::new(metadata)take no manifest, and the manifest-driven React island bootstrap is gone. Removed:IslandManifestand its entry types,RouteResponse::with_islandsandwith_bootstrap,render_bootstrap_for_islands,css_asset_path,render_css_link, and the router'sExtension<Arc<IslandManifest>>. The finalizers (finalize_route_response*,render_*_html_response,into_framework_response) lose their manifest parameter. Link a stylesheet from the layout withcx.url(..).proa_reactislands keep rendering throughproa::react::react_bootstrapdirectly.RouteResponse::render_to_bytesrenders a finalized document with no server or runtime. See Configuration and Route responses.- Application URL composition now lives on
cx.url(path). Move outgoing URL construction offcx.request(). The helper explicitly applies the configured base path and writes directly into HTML attributes or Markdown links; plain URL strings stay unchanged. See Linking. - The unused legacy effect IR and fluent expression builder are gone. Browser effects use RSJS. The
proa_irexpression/value model, bounded evaluator, reactive bindings, and component trees remain available. - The deprecated pool-backed writers are gone. Replace
SinkWriter,SinkPage,PagePool,MemorySink, their in-order aliases, andSinkCheckpointwithRenderBufferand its checkpoints. Custom transport adapters keep usingStreamChunkFlusher/SendStreamChunkFlusher. See WriteBuf. - The file-backed action collision checker is gone. Remove calls to
proa::actions::check_action_collisionsandclear_action_registry, and imports fromcollision_check. The action derive never populated that registry. Scoped action names and the action data/code generation APIs remain available. - The standalone
proa_codegencrate andproa-codegenbinary are gone. Component libraries own their metadata-to-TypeScript generation; Proa UI has its own generators.proa new sitecontinues to use the CLI's site scaffolder. - The old
proa_cli::scaffold::new_siteRust API is gone. Use theproa new sitecommand, which usessite_scaffold. The component, layout, and data generators remain available. - Generators no longer add placeholder render or source-text tests. The page, endpoint, and component generators no longer accept
--no-test. ORIGIN keeps its loader and runtime integration tests without a full-page HTML snapshot. - The unused
ProaConfigAPI is gone, includingPathsConfig,CodegenConfig,ServerConfig, andFrameworkBuilder::{with_config, config}. Those values did not affect the router. Mount assets withwith_static_service, configure middleware through the builder, and bind your listener to select the host and port. See Configuration. - Unused framework side features are gone:
ExternalApp,ExternalAppStrategy,FrameworkBuilder::with_external_app, theproxy,process_manager, andshardmodules, and theroute-exportfeature/module. Compose static applications through Axum's router APIs and manage upstream processes and proxies in your deployment. RoutePageCacheand the generic readiness probes remain available. - Unused compatibility helpers are gone. Use
RenderBufferinstead ofDefaultChainedBumpWriter,load_json*/load_typed*instead of the deprecated contextload*aliases, anddrain_pending_boundaries_with_artifactsordrain_pending_boundaries_with_nonce_and_artifactsfor deferred streaming output. Use[u8; N]orSmallBuf<N>directly instead of the fixed-size aliases instack; construct aWebContextwith your writer instead ofrender_into_vec_with_hint.
Good to know: The linked-pipeline change is the one most likely to surprise CI. If your pipeline runs
cargo build, switch it tocargo proa build. See CI / GitHub Actions.
When an upgrade breaks the build
Work in this order, because each step rules out the next:
- Read the changelog entry for every version you crossed. Breaking changes are marked.
- Run
cargo proa check, notcargo check. Template lints and linker errors only appear in the former. - Check the RSJS boundary. Most post-0.3 breakage is a component that used to be implicitly analysed and now needs an explicit
#[rsjs(component)]or#[rsjs(component, client)]. - Check your buffer. If a custom writer stopped compiling, move to
RenderBuffer. - Search Troubleshooting for the exact diagnostic text.
Next steps
- Troubleshooting
- Fix the most common Proa setup, registry, template, component, island, routing, and CI failures.
- CI / GitHub Actions
- Gate pull requests with proa check, then deploy from the same pipeline.
- HTML rendering
- Render typed Rust values to HTML with render traits and the html! macros.
- WriteBuf
- Pick the buffer a route renders into.
- proa fmt / lint / check
- Format macro bodies, run lints, and gate CI.