
Text.js: Build full-stack React apps that render inside console.log
Build full-stack React apps that render inside console.log.
以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。
Build full-stack React apps that render inside console.log.
This page is running in your console. Open it with ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C (turn on developer features first), click the preview below and press ↑ ↓.
1import { useState } from "react";2import { AsciiFont, Box, Text, useInput } from "@textjs/app";34export default function Page() {5 const [count, setCount] = useState(0);6 useInput((e) => {7 if (e.key === "up") setCount((c) => c + 1);8 if (e.key === "down") setCount((c) => c - 1);9 });1011 return (12 <Box className="flex-col gap-1 p-2">13 <AsciiFont text="▼ TEXT.JS" />14 <Text color="muted">React 19 in console.log</Text>15 <Text bold color="accent">count = {count}</Text>16 </Box>17 );18}
ElementsConsoleSourcesNetworkPerformanceMemoryApplication
top ▾FilterDefault levels ▾No Issues
viewport:3⌨ Click to focus
›
React 19
Text.js supports concurrent rendering, Suspense and error boundaries.
Folders in app/ become routes and layouts, and Back, Forward and deep links work.
The grid fits the docked DevTools panel at any page zoom.
Keys, paste and IME composition reach the app through one hidden <textarea>.
ElementsConsoleSourcesNetworkPerformanceMemoryApplication
top ▾-url:preview://tableDefault levels ▾No Issues
preview://table:1⌨ Click to focus
›
↑ ↓ move · s sort · Space selectRun in consoleDocs
Layout<Box>
<Stack> <Grid> <SplitPane> <ScrollBox> <Center>Data<List>
<Table> <Tree> <Markdown> <Code> <Diff>Charts<LineChart>
<BarChart> <Sparkline> <ProgressBar> <Gradient> <Image>Controls<Input>
<Select> <Checkbox> <Switch> <Slider> <Dialog>KeyboarduseKeymap
<KeyHelp> <KeyHints> <CommandPalette> <StatusBar>useFocus
Every changed frame is one console.log call
A commit that changes no cells never reaches the console.
<Box> ├ <Text> └ <Text> 101Commit
React commits through a custom reconciler.
Clearing the console before each frame leaves it blank until DevTools paints the next one. Turbolog appends each frame instead.
clear() + log()70.6% blank
log(), appended1.0% blank
0.163msFull repaint (layout, paint, encode)
0.011msOne-row edit, such as a keystroke
0 callsIdle frame
149 spans%c arguments for 3,200 cells
100×32 dashboard, mean of 1,000 frames · Apple M5 Pro · Bun 1.4.4Turbolog engine docs
Render routes on the server
Export runtime = "server" to render a route and its async components on the server. The browser loads a 21 kB (gzip) frame player instead of your app.
1import { Suspense } from "react";2import { Box, Text } from "@textjs/app";3import { db } from "@/lib/db";45export const runtime = "server";67async function Deploys() {8 const rows = await db.deploys.latest(5);9 return rows.map((d) => (10 <Text key={d.id}>{${d.state} ${d.branch}}</Text>11 ));12}1314export default function Page() {15 return (16 <Box className="flex-col p-1">17 <Text bold>Deployments</Text>18 <Suspense fallback={<Text color="muted">Loading…</Text>}>19 <Deploys />20 </Suspense>21 </Box>22 );23}
ServerReact + Yoga
SSE · row deltas
Frame player21 kB gzip
DevToolsconsole.log
Partial PrerenderingEvery static route’s first frame ships inside its HTML. The console paints before JavaScript loads.
Middlewaremiddleware.ts runs before matched requests, with NextRequest, NextResponse and config.matcher.
Cachingrevalidate, unstable_cache and revalidateTag cache route handlers and data, with stale-while-revalidate.
Deploy adapterstext build --adapter targets static, bun, vercel or cloudflare. Server-rendered routes need bun or text start.
Also runs in terminals and agents
ElementsConsoleSources
VM12:1▼ Acme Deploys main
● Ready web iad1 2m
● Ready api sfo1 4m
◌ Build docs fra1 42%
DevToolstext dev
Turbolog writes each frame as %c spans in one console.log.
text run renders the same App Router app in truecolor ANSI and runs route handlers in-process.
Over MCP, agents navigate routes, press keys and read each frame as plain text.
Code with OpenCode in DevTools
OpenCode Lite is the OpenCode TUI rebuilt with Text.js to run in your browser console.
ElementsConsoleSourcesNetworkPerformanceMemoryApplication
top ▾FilterDefault levels ▾No Issues
The reconnect test is flaky… +
→ Explored: 1 search, 1 read
The client closes on the first onerror and never reconnects. I'll retry instead.
┃
┃ ← Edit src/events.ts
┃
┃ 1 export function connect(url: string, onEvent: (e: Event) => void) {
┃ 2 const source = new EventSource(url);
┃ 3 source.onmessage = (m) => onEvent(JSON.parse(m.data));
┃ 4 - source.onerror = () => source.close();
┃ 4 + source.onerror = () => {
┃ 5 + source.close();
┃ 6 + setTimeout(() => connect(url, onEvent), 250);
┃ 7 + };
┃ 8 return () => source.close();
┃ 9 }
┃
┃
┃ $ bun test test/events.test.ts
┃
┃ 3 pass, 0 fail
┃
Fixed. connect() now reconnects after an error. All 3 tests pass, including the flaky one.
Build · Claude Opus 5.5 · 2.5s
┃
┃
┃
┃ Build · Claude Opus 5.5 Anthropic
╹▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
~/code/textjs:main 12.7K (3%) · $0.02 ctrl+p commands
opencode:1
›
Sandbox
A scripted agent answers any prompt, with nothing to install.
Run bunx @textjs/opencode@latest proxy and enter the code it prints. The page connects to OpenCode on your machine.
Pick any model your server has configured with /models. Sessions, agents and models come from your OpenCode server.
Adds a panel with the component tree, a frame inspector and a per-frame timeline.
Previews the frame next to your code and scaffolds App Router files.
Catches DOM tags in console components, boxes inside text and glyphs Menlo doesn’t have.
Render offscreen, press keys and assert on lastFrame() in any test runner.
Errors and warnings with a TX code link to a page that explains the fix.
Pause, resize, wireframe and copy the running app from the console prompt.
Implements the Unicode Bidirectional Algorithm and passes all 770,241 BidiTest.txt cases.
Parses .flf files and matches 273 outputs recorded from the figlet binary.
The free course has 10 chapters and takes about 65 minutes.
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。