Components
Build
Docs
Code
Deploy
Data
Test
Safety
Run
Package

prototype.rs

A gentle prototyping toolkit for Rust, where every component snaps together like carefully curated building blocks.

Getting Started

Why prototype.rs?

Prototyping in Rust often feels like building a bridge before you know where the river is. prototype.rs flips the process: start with a sketch, refine iteratively, and let the compiler guide your design decisions rather than fight them.

cargo.toml
// Add to your dependencies
[dependencies]
prototype = "0.4.2"
tokio = { version = "1", features = ["full"] }
Start here

Design philosophy

Every component is a self-contained module. No hidden state, no implicit dependencies. Like arranging items on a clean workshop table, each piece reveals its purpose through its shape.

main.rs
use prototype::{Sketch, Component};

fn main() {
    let sketch = Sketch::new("my-app")
        .add(Component::router())
        .add(Component::store())
        .add(Component::view("home"));

    sketch.build();
}
Three lines to a working prototype

The compiler is your pair programmer. Let it guide your iterations.

Components
Core Concepts

How components connect

SketchRouterStoreViewOutput

Sketch as blueprint

A Sketch is the root container for your prototype. Think of it as the workshop table itself — components are placed onto it, and their connections are automatically inferred from their types and capabilities.

components.rs
// Define a custom component
use prototype::Component;

struct AuthLayer {
    provider: String,
    redirect: String,
}

impl Component for AuthLayer {
    fn name(&self) -> &str {
        "auth"
    }

    fn depends_on(&self) -> Vec<&str> {
        vec!["router", "store"]
    }
}

Trait-based composition

Every component implements the Component trait. Dependencies are declared explicitly — the Sketch resolver validates the graph at compile time, ensuring no missing connections or circular dependencies.

Zero-cost abstractions mean your prototype compiles to the same assembly as hand-written code.

Patterns
Building Blocks

Router

The Router maps URL patterns to view handlers. It supports nested routes, parameter extraction, and guard middleware. Every route is type-checked, so a typo in a path pattern fails at compile time, not at runtime.

router.rs
let router = Component::router()
    .route("/", home_view)
    .route("/users/:id", user_view)
    .route("/api/*", api_handler)
    .fallback(not_found);
Type-safe URL patterns

Store

The Store is a reactive state container. State mutations trigger targeted re-renders through a fine-grained subscription system. No virtual DOM, no diffing — just precise updates where they matter.

store.rs
let store = Component::store()
    .state(AppState {
        count: 0,
        user: None,
    })
    .reducer("increment", |state| {
        state.count += 1;
    });

Reducers are pure functions. Side effects live in middleware, keeping your state transitions predictable.

View

Views are declarative templates that subscribe to Store slices. When state changes, only the affected view fragments re-render. The template syntax is Rust-native — no separate template language to learn.

Middleware
Advanced

Middleware pipeline

RequestLoggerAuthHandlerResponse

Middleware chains

Middleware wraps your handlers in composable layers. Each layer can inspect, modify, or short-circuit the request pipeline. Stack them like building blocks — logging, authentication, rate-limiting, caching — in any order.

middleware.rs
let sketch = Sketch::new("app")
    .middleware(Logger::default())
    .middleware(Auth::bearer("secret"))
    .middleware(RateLimit::per_minute(100))
    .add(Component::router())
    .build();
Composable layers, zero overhead

Built-in testing

Every component comes with a mock counterpart. Test your prototype in isolation with deterministic state, simulated routing, and assertion helpers that speak Rust's testing idioms.

tests.rs
#[test]
fn test_increment() {
    let store = MockStore::new(
        AppState { count: 0 }
    );
    store.dispatch("increment");
    assert_eq!(store.state().count, 1);
}

Every prototype is testable by default. No setup ceremony, no framework boilerplate.

Deploy
Community

Ecosystem

prototype.rs integrates with the Rust ecosystem you already know. Use your favorite crates alongside prototype components — serde for serialization, tokio for async, tracing for observability. No walled garden.

From prototype to production

When your prototype proves its shape, graduate it. prototype.rs generates production-ready scaffolding from your Sketch — complete project structure, CI configuration, deployment manifests — all derived from the components you already assembled.

terminal
# Graduate your prototype
$ cargo prototype graduate

# Generated structure:
src/
  handlers/
  models/
  middleware/
tests/
Dockerfile
fly.toml
One command to production

Your prototype is never throwaway code. It is the seed of your production system.

Open source

prototype.rs is MIT licensed and community-driven. Browse the source, submit components, or fork your own flavor. The workshop is open.

Begin