Skip to content
Conduit

mcp server

proa

Proa-Labs/proacommunitylistedunreviewed

Set up

Hosted by its author. Add the URL to your agent — nothing to install.

~/Library/Application Support/Claude/claude_desktop_config.json
Settings → Connectors → Add custom connector

Name: proa
URL:  https://proa.so/mcp

same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12

Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs

README

synced Nov 1, 2026

Proa

The next era of web interfaces. Built in Rust.

Proa is building the next generation of interface infrastructure for the web. It enables you to create extremely fast, scalable applications and services in Rust by bringing compiled components, streaming, data loading, and fine-grained interactive islands into one framework.

Axum adapter Core Macros RSJS License X Reddit

Get started · Explore apps · See the benchmarks


A programming model for multiple interfaces

Proa's larger vision is one typed, compiled interface layer that produces the right representation for whoever asks: complete HTML for people, targeted behavior for browsers, and dense machine-readable output for agents.

This repository provides the compiled renderer, built-in render traits for HTML and Markdown, browser interactivity, streaming, data loading, and framework tooling. Other render targets can define their own rendering implementations, whether for a format such as JSON or for a native rendering backend.

Start in five minutes

Install the latest stable CLI through Cargo using a current Rust toolchain:

cargo install proa-cli --locked

Once installed, update with proa update, or preview the latest stable version with proa update --check.

Follow the quickstart to install the styling tools, create a site, edit its first route, and run Proa's checks.

Your first page is a typed Rust component

Use WebRenderSync and html_sync! for the normal fast path:

use proa_core::{DataLoader, WebContext, WebRenderSync, WriteError};
use proa_macros::html_sync;

struct Greeting {
    name: String,
}

impl<L: DataLoader> WebRenderSync<L> for Greeting {
    fn render(self, cx: &mut WebContext<L>) -> Result<(), WriteError> {
        html_sync! {
            <main class="mx-auto max-w-3xl px-6 py-16">
                <h1 class="text-4xl font-semibold">"Hello, "{self.name}</h1>
                <p class="mt-4 text-zinc-600">"Rendered by Proa."</p>
            </main>
        }
        .render(cx)
    }
}

The macro validates the template at compile time, consolidates adjacent static markup, and preserves the correct escaping behavior for dynamic slots.

When a component genuinely needs to await work, switch to WebRender and html!. Markdown follows the same split with MdRenderSync / md_sync! and MdRender / md!.

Add interactivity where it belongs

An RSJS island is still a normal server component. Add signals and event handlers, and Proa emits the server-rendered HTML plus the JavaScript required for that island:

use proa_core::{DataLoader, WebContext, WebRenderSync, WriteError};
use proa_macros::html_sync;
use rsjs::{rsjs, signal};

struct Counter {
    initial: i32,
}

#[rsjs(component, client)]
impl<L: DataLoader> WebRenderSync<L> for Counter {
    fn render(self, cx: &mut WebContext<L>) -> Result<(), WriteError> {
        let count = signal(self.initial);

        html_sync! {
            <button
                data-counter
                type="button"
                on_click={|_| count.update(|value| value + 1)}
            >
                "Count: "{count.get()}
            </button>
        }
        .render(cx)
    }
}

The browser starts from the HTML the server already rendered. It does not re-run the server component tree to make the page interactive. See the RSJS guide for composition, queries, shared state, forms, and current limitations.

Markdown interfaces with MdRender

A component can expose both an HTML page and a Markdown document from the same data. Give the Greeting component above a Markdown implementation:

use proa_core::{DataLoader, WebContext, MdRenderSync};
use proa_macros::md_sync;

impl<L: DataLoader> MdRenderSync<L> for Greeting {
    fn render_md(self, cx: &mut WebContext<L>) -> Result<(), WriteError> {
        md_sync! { r###"
            # Hello, {self.name}

            Rendered by Proa.
            "###
        }
        .render_md(cx)
    }
}

MdRenderSync and md_sync! are the synchronous path. Use MdRender and md! when a Markdown component needs to await work. Interpolated values are escaped, and typed children compose into larger documents. Both renderers use the same component data and define their own output.

For an existing synchronous HTML component, enable the core crate's html-to-markdown feature and delegate with proa_core::to_markdown(self).render_md(cx). The adapter captures its HTML and converts semantic elements to Markdown. It allocates during conversion; handwritten Markdown remains the fast path and controls custom representations. See the HTML-to-Markdown example.

See the Markdown rendering guide for composition, async rendering, and serving Markdown alongside HTML.

Technical Approach

We treat web rendering as a serialization problem, not a component-tree reconstruction problem. A server should turn application state into useful HTML as directly as possible: emit as much HTML and as little JavaScript as possible, as fast as possible.

JavaScript is expensive. The browser must download it, parse it, compile it, and execute it—often on the main thread. That is expensive on desktop and worse on mobile CPUs; it can take 6-10x longer to execute on lower tier android devices. It also consumes memory and battery. Proa treats every byte of client code as work that must justify itself. For more, see Addy Osmani's "The Cost of JavaScript"

Benchmarks

For more benchmarks, see Proa-Labs/proa-benchmarks.

How fast does a fresh process answer? Spawn to first complete response, the cost of every autoscaling event and cold instance: Proa answered in 8.63 ms holding 4.5 MiB, against 69.0 ms and 75.9 MiB for React, 57.0 ms and 63.0 MiB for Marko, and 15.2 ms and 12.5 MiB for Go.

The parity gate, the one-core rule, the load generator's self-checks, what is deliberately left outside each measurement, every raw JSON capture, and the commands to reproduce all of it on your own hardware are documented in Proa-Labs/proa-benchmarks.

Proa in production

  • latency.so: a server-side rendering speed leaderboard, server-rendered with Proa.

Explore the project

If you want to…Start here
Build your first Proa siteGetting started
Understand the benchmark claimsBenchmarks and the full evidence repository
Author server-rendered componentsproa_core and proa_macros
Build interactive islandsRSJS
Load data and stream independent boundariesproa_stream and the data-loading guide
Integrate routing, security, and Axumproa_framework_axum
Adapt Proa to another HTTP server or runtimeproa_framework_core
Compile documentation and self-hosted fontsproa_docs and proa_fonts
Embed rendering in an existing serviceFFI guide
Contribute to ProaContributing guide
Give a coding agent project contextAgent authoring guide

Repository development

Prerequisites:

  • Rust 1.93.0 or newer
  • Python 3 for repository lint scripts
  • Node.js 22 or newer for browser conformance tests and JavaScript comparison engines

Run the workspace checks from the repository root:

cargo fmt --all
cargo check --workspace --all-targets
cargo test --workspace --no-fail-fast
python3 scripts/proa_perf_lint.py

Run the marketing site and documentation locally with:

cargo proa run -p proa_marketing --bin proa_marketing

This repository contains the compiled-template engine and its first-party framework, tooling, examples, and RSJS compiler. Runtime templates and the proa_ui component library are downstream projects with independent release processes.

Security issues should be reported privately according to SECURITY.md. Generated and captured assets are documented in GENERATED.md.

License

Proa is licensed under the Apache License, Version 2.0. See LICENSE, copyright 2026 Proa Labs, Inc.

Commercial use, including inside closed-source products, is permitted with no separate agreement. See LICENSING.md for details or contact legal@proa.so. Third-party attributions are collected in THIRD_PARTY_NOTICES.md.

↑↓ navigate openesc close