コンソールのフレームワーク

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回呼び出し

セルに変更がないコミットはコンソールに届きません。

  1. React 19

    01コミット

    Reactはカスタムリコンサイラーを通じてコミットします。

  2. Yoga

    02レイアウト

    Yogaがボックスを整数セル単位で配置します。

  3. CellBuffer

    03描画

    変更のある行のみ再描画します。

  4. 行ハッシュ

    04変更判定ゲート

    変更のないフレームはここで止まります。

  5. RLE

    05エンコード

    3,200セルを149個の%cスパンに変換します。

  6. console.log

    06出力

    フレームは66ms以上の間隔で追記します。

変更のあるフレーム 変更のないフレーム、0回の呼び出し

フレームの追記

フレームごとにコンソールを消去すると、DevToolsが次のフレームを描画するまで空白になります。Turbologは代わりに各フレームを追記します。

記事を読む
clear() + log()70.6%が空白
log(), appended1.0%が空白
0.163ms全面再描画(レイアウト、描画、エンコード)
0.011msキー入力などの1行編集
0回の呼び出しアイドル時のフレーム
149個のスパン3,200セル分の%c引数
100×32ダッシュボード、1,000フレームの平均 · 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です。

サンドボックス

スクリプトで動くエージェントがあらゆるプロンプトに応答します。インストールは不要です。

1つのコマンド

bunx @textjs/opencode@latest proxyを実行し、表示されたコードを入力します。ページがマシン上のOpenCodeに接続します。

自分のモデルとセッション

/modelsでサーバーに設定済みのモデルを選択します。セッション、エージェント、モデルは自分のOpenCodeサーバーから取得します。