# @react-fullstack/render

> render react tree to nothing!

Latest version **0.3.1-alpha.8** (published 2022-12-06) · MIT license · 0 weekly downloads

## Install

```sh
npm install @react-fullstack/render
pnpm add @react-fullstack/render
yarn add @react-fullstack/render
bun add @react-fullstack/render
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.3.1-alpha.8 |
| Published | 2022-12-06 |
| First published | 2020-08-29 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 1 |
| Unpacked size | 9.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | shmuelhizmi |
| Maintainers | shmuelhizmi |
| Keywords | react, express, typescript, http |

## Links

- npm: https://www.npmjs.com/package/@react-fullstack/render
- Repository: https://github.com/shmuelhizmi/react-fullstack
- Homepage: https://github.com/shmuelhizmi/react-fullstack#readme
- Issues: https://github.com/shmuelhizmi/react-fullstack/issues
- npm.io page: https://npm.io/package/@react-fullstack/render

## Dependencies (1)

- [react-test-renderer](https://npm.io/package/react-test-renderer.md) 18.2.0

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.3.1-alpha.8 (latest) — 2022-12-06
- 0.3.1-alpha.7 (alpha) — 2022-11-19
- 0.3.1-alpha.6 — 2022-11-19
- 0.3.1-alpha.5 — 2022-11-19
- 0.3.0 — 2022-05-12
- 0.3.0-alpha.1 — 2022-04-03
- 0.2.2 — 2021-05-08
- 0.2.1 — 2021-03-28
- 0.2.0 — 2021-03-28
- 0.1.23 — 2020-10-10
- 0.1.21 — 2020-09-05
- 0.1.18 — 2020-09-04
- 0.1.17 — 2020-09-03
- 0.1.16 — 2020-09-03
- 0.1.11 — 2020-09-02
- … 2 more at https://npm.io/package/@react-fullstack/render/versions

## README

# echoform

Build web UIs where all logic stays on the server. The browser is just a screen.

echoform is for dev tools, local apps, and anywhere you want a web interface without building an API layer. You write React on the server — state, callbacks, streaming — and echoform handles the rest.

```bash
bun add @playfast/echoform @playfast/echoform-render
bun add @playfast/echoform-bun-ws-server  # server
bun add @playfast/echoform-bun-ws-client   # client
bun add zod  # or valibot, arktype — any Standard Schema library
```

## Example: System Monitor

A live process monitor in ~40 lines of server code. The client is just HTML — zero business logic.

> [Full source](demo/system-monitor)

### 1. Define the contract

```typescript
// shared/views.ts
import { view, callback, stream, createViews } from "@playfast/echoform";
import { z } from "zod";

export const Dashboard = view("Dashboard", {
  input: {
    hostname: z.string(),
    cpuUsage: z.number(),
    memoryUsed: z.number(),
    memoryTotal: z.number(),
  },
});

export const ProcessTable = view("ProcessTable", {
  input: {
    processes: z.array(z.object({
      pid: z.number(), name: z.string(), cpu: z.number(), memory: z.number(),
    })),
  },
  callbacks: {
    onKill: callback({ input: z.number() }),
    onRefresh: callback(),
  },
});

export const LogStream = view("LogStream", {
  streams: { lines: stream(z.string()) },
});

export const views = createViews({ Dashboard, ProcessTable, LogStream });
```

### 2. Server — all logic lives here

```typescript
// server/index.tsx
import os from "os";
import { Render } from "@playfast/echoform-render";
import { Server, useStream } from "@playfast/echoform/server";
import { createBunWebSocketServer } from "@playfast/echoform-bun-ws-server";
import { Dashboard, ProcessTable, LogStream } from "../shared/views";

function Monitor() {
  const log = useStream(LogStream, "lines");
  const [processes, setProcesses] = useState([]);

  useEffect(() => {
    const refresh = async () => {
      setProcesses(await getProcessList());
    };
    refresh();
    const interval = setInterval(refresh, 2000);
    return () => clearInterval(interval);
  }, []);

  return (
    <>
      <Dashboard
        hostname={os.hostname()}
        cpuUsage={getCpuUsage()}
        memoryUsed={os.totalmem() - os.freemem()}
        memoryTotal={os.totalmem()}
      />
      <ProcessTable
        processes={processes}
        onKill={(pid) => {
          process.kill(pid, "SIGTERM");
          log.emit(`Killed PID ${pid}`);
        }}
        onRefresh={() => refresh()}
      />
      <LogStream lines={log} />
    </>
  );
}

const { transport, start } = createBunWebSocketServer({ port: 4231, path: "/ws" });
start();

Render(
  <Server transport={transport}>
    {() => <Monitor />}
  </Server>
);
```

### 3. Client — just renders what the server sends

```typescript
// client/index.tsx
import { Client } from "@playfast/echoform/client";
import { useWebSocketTransport } from "@playfast/echoform-bun-ws-client";
import { Dashboard, ProcessTable, LogStream } from "./components";

function App() {
  const { transport } = useWebSocketTransport("ws://localhost:4231/ws");
  if (!transport) return <div>Connecting...</div>;
  return <Client transport={transport} views={{ Dashboard, ProcessTable, LogStream }} />;
}
```

Client components receive typed props — `.mutate()` for callbacks, `.subscribe()` for streams:

```typescript
// client/components.tsx
function ProcessTable({ processes, onKill, onRefresh }: InferClientProps<typeof ProcessTableDef>) {
  return (
    <table>
      {processes.map((proc) => (
        <tr key={proc.pid}>
          <td>{proc.name}</td>
          <td>{proc.cpu}%</td>
          <td><button onClick={() => onKill.mutate(proc.pid)}>Kill</button></td>
        </tr>
      ))}
      <button onClick={() => onRefresh.mutate()}>Refresh</button>
    </table>
  );
}
```

The server reads system data, manages state, handles kill signals. The client is a dumb terminal. echoform bridges them transparently over WebSocket.

## API

### View Builders (`@playfast/echoform`)

| Function | Description |
|----------|-------------|
| `view(name, config)` | Define a view — returns a React component usable as JSX on the server |
| `callback(config?)` | Define a callback with optional input/output schemas |
| `stream(schema)` | Define a server→client stream with chunk schema |
| `createViews(record)` | Compose view definitions into a registry (optional, for validation) |

### Server (`@playfast/echoform/server`)

| Export | Description |
|--------|-------------|
| `useStream(viewDef, name)` | Create a `StreamEmitter` for pushing data to clients |
| `Server` | Root component that manages client connections |

### Client (`@playfast/echoform/client`)

| Export | Description |
|--------|-------------|
| `Client` | Root component that renders views from the server |
| `InferClientProps<V>` | Infer client-side props from a view definition |

### Client Callback Shape

```typescript
callback.mutate(input)        // Call the server handler, returns Promise
callback.queryOptions()       // { mutationFn, mutationKey } for useMutation
```

### Client Stream Shape

```typescript
stream.subscribe(listener)    // Returns unsubscribe function
```

### Transport (`@playfast/echoform-bun-ws-client`)

```typescript
const { transport, error, status } = useWebSocketTransport(url);
```

## Packages

- [@playfast/echoform](packages/echoform) — core framework
- [@playfast/echoform-render](packages/react-render-null) — server-side React renderer

## Transport Plugins

- [@playfast/echoform-bun-ws-server](plugins/echoform/bun-ws-server) — Bun WebSocket server
- [@playfast/echoform-bun-ws-client](plugins/echoform/bun-ws-client) — WebSocket client hook
- [@playfast/echoform-socket-server](plugins/echoform/socket-server) — Socket.io server
- [@playfast/echoform-socket-client](plugins/echoform/socket-client) — Socket.io client

## Demos

- [System Monitor](demo/system-monitor) — live process monitor with kill, streams, and system stats
- [Todo App](demo/todo-app) — CRUD with callbacks and zod schemas
- [File Editor](demo/file-editor) — Monaco editor with file tree
- [Dev Server](demo/dev-server) — multi-process terminal dashboard

---
_Source: https://npm.io/package/@react-fullstack/render · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
