Das Konsolen-Framework

Entwickle Full-Stack-React-Apps, die in console.log rendern.

Loslegen

Diese Seite läuft in deiner Konsole. Öffne sie mit ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C (zuerst Entwicklerfunktionen aktivieren), klicke auf die Vorschau unten und drücke ↑ ↓.

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}
viewport:3

React 19

Text.js unterstützt nebenläufiges Rendering, Suspense und Error Boundaries.

App Router

Ordner in app/ werden zu Routen und Layouts, und Zurück, Vorwärts und Deep-Links funktionieren.

Responsives Raster

Das Raster passt bei jeder Zoomstufe in das angedockte DevTools-Panel.

Tastatureingabe

Tastendrücke, Einfügen und IME-Komposition erreichen die App über ein verborgenes <textarea>.

Tabellen, Diagramme, Formulare und Tastenkürzel

Live
preview://table:1
↑ ↓ bewegen · s sortieren · Space auswählen
Dokumentation
Layout
  • <Box>
  • <Stack>
  • <Grid>
  • <SplitPane>
  • <ScrollBox>
  • <Center>
Daten
  • <List>
  • <Table>
  • <Tree>
  • <Markdown>
  • <Code>
  • <Diff>
Diagramme
  • <LineChart>
  • <BarChart>
  • <Sparkline>
  • <ProgressBar>
  • <Gradient>
  • <Image>
Steuerelemente
  • <Input>
  • <Select>
  • <Checkbox>
  • <Switch>
  • <Slider>
  • <Dialog>
Tastatur
  • useKeymap
  • <KeyHelp>
  • <KeyHints>
  • <CommandPalette>
  • <StatusBar>
  • useFocus

Jeder geänderte Frame ist ein console.log-Aufruf

Ein Commit ohne geänderte Zellen erreicht die Konsole nie.

  1. React 19

    01Commit

    React führt Commits über einen eigenen Reconciler aus.

  2. Yoga

    02Layout

    Yoga ordnet Boxen auf ganzen Zellen an.

  3. CellBuffer

    03Zeichnen

    Nur beschädigte Zeilen werden neu gezeichnet.

  4. Zeilen-Hash

    04Änderungsfilter

    Unveränderte Frames stoppen hier.

  5. RLE

    05Kodieren

    3.200 Zellen werden zu 149 %c-Spans.

  6. console.log

    06Ausgeben

    Frames werden mit mindestens 66 ms Abstand angehängt.

Geänderter Frame Unveränderter Frame, 0 Aufrufe

Angehängte Frames

Wird die Konsole vor jedem Frame geleert, bleibt sie leer, bis DevTools den nächsten zeichnet. Turbolog hängt stattdessen jeden Frame an.

Beitrag lesen
clear() + log()70.6 % leer
log(), appended1.0 % leer
0.163msKomplett neu zeichnen (Layout, Zeichnen, Kodieren)
0.011msEinzelne Zeile ändern, etwa per Tastendruck
0 AufrufeFrame im Leerlauf
149 Spans%c-Argumente für 3200 Zellen
100×32-Dashboard, Mittelwert aus 1000 Frames · Apple M5 Pro · Bun 1.4.4Dokumentation zur Turbolog-Engine

Routen auf dem Server rendern

Exportiere runtime = "server", um eine Route und ihre asynchronen Komponenten auf dem Server zu rendern. Der Browser lädt einen 21 kB (gzip) großen Frame-Player statt deiner 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}

Mit OpenCode in DevTools programmieren

OpenCode Lite ist die mit Text.js nachgebaute OpenCode-TUI für deine Browserkonsole.

Sandbox

Ein skriptgesteuerter Agent beantwortet jeden Prompt, ohne Installation.

Ein Befehl

Führe bunx @textjs/opencode@latest proxy aus und gib den ausgegebenen Code ein. Die Seite verbindet sich mit OpenCode auf deinem Rechner.

Deine Modelle und Sitzungen

Wähle mit /models ein Modell, das dein Server konfiguriert hat. Sitzungen, Agenten und Modelle kommen von deinem OpenCode-Server.