主控台框架

建構在 console.log 內渲染的全端 React 應用程式。

開始使用

此頁面正在你的主控台執行。按 ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C 開啟主控台(請先啟用開發者功能),點選下方預覽並按 ↑ ↓。

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 支援並行渲染、Suspense 與錯誤邊界。

App Router

app/ 中的資料夾會成為路由與版面配置,並支援上一頁、下一頁與深層連結。

響應式網格

無論頁面縮放比例為何,網格都會符合停駐的 DevTools 面板。

鍵盤輸入

按鍵、貼上與 IME 組字會透過一個隱藏的 <textarea> 傳入應用程式。

表格、​圖表、​表單與​快速鍵

即時
preview://table:1
↑ ↓ 移動 · s 排序 · Space 選取
文件
版面配置
  • <Box>
  • <Stack>
  • <Grid>
  • <SplitPane>
  • <ScrollBox>
  • <Center>
資料
  • <List>
  • <Table>
  • <Tree>
  • <Markdown>
  • <Code>
  • <Diff>
圖表
  • <LineChart>
  • <BarChart>
  • <Sparkline>
  • <ProgressBar>
  • <Gradient>
  • <Image>
控制項
  • <Input>
  • <Select>
  • <Checkbox>
  • <Switch>
  • <Slider>
  • <Dialog>
鍵盤
  • useKeymap
  • <KeyHelp>
  • <KeyHints>
  • <CommandPalette>
  • <StatusBar>
  • useFocus

每個已變更的影格​呼叫一次 console.log

未變更任何儲存格的提交不會傳到主控台。

  1. React 19

    01提交

    React 透過自訂協調器提交更新。

  2. Yoga

    02版面配置

    Yoga 以完整儲存格為單位配置方塊。

  3. CellBuffer

    03繪製

    僅重繪受損的列。

  4. 列雜湊

    04變更檢查關卡

    未變更的影格到此停止。

  5. RLE

    05編碼

    3,200 個儲存格轉為 149 個 %c span。

  6. console.log

    06輸出

    附加影格至少間隔 66 ms。

已變更的影格 未變更的影格,0 次呼叫

附加的影格

每個影格前清除主控台,會讓主控台保持空白,直到 DevTools 繪製下一個影格。Turbolog 改為附加每個影格。

閱讀文章
clear() + log()70.6% 空白
log(), appended1.0% 空白
0.163ms完整重繪(版面配置、繪製、編碼)
0.011ms單列編輯,例如按鍵輸入
0 次呼叫閒置影格
149 個 span3200 個儲存格的 %c 引數
100×32 儀表板,1000 個影格的平均值 · Apple M5 Pro · Bun 1.4.4Turbolog 引擎文件

在伺服器上​渲染路由

匯出 runtime = "server",在伺服器上渲染路由及其非同步元件。瀏覽器會載入 21 kB(gzip)的影格播放器,取代你的應用程式。

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}

在 DevTools 用 OpenCode 寫程式

OpenCode Lite 是以 Text.js 重建的 OpenCode TUI,在瀏覽器主控台中執行。

沙箱

腳本代理會回答任何提示,無須安裝。

一行指令

執行 bunx @textjs/opencode@latest proxy,並輸入輸出的代碼。頁面會連線至你電腦上的 OpenCode。

你的模型​與工作階段

使用 /models 選擇伺服器已設定的任意模型。工作階段、代理與模型皆來自你的 OpenCode 伺服器。