콘솔 프레임워크
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}React 19
Text.js는 동시 렌더링, Suspense, 에러 바운더리를 지원해요.
App Router
app/의 폴더는 라우트와 레이아웃이 되고, 뒤로 가기, 앞으로 가기, 딥 링크가 작동해요.
반응형 그리드
페이지 확대 비율에 관계없이 그리드가 도킹된 DevTools 패널에 맞춰져요.
키보드 입력
키 입력, 붙여넣기, IME 조합이 숨겨진 <textarea> 하나로 앱에 전달돼요.
표, 차트, 폼과 단축키
변경된 프레임마다 console.log 호출 1회
셀을 바꾸지 않는 커밋은 콘솔에 도달하지 않아요.
- React 19
01커밋
React는 커스텀 리컨실러로 커밋해요.
- Yoga
02레이아웃
Yoga는 박스를 정수 단위 셀에 배치해요.
- CellBuffer
03그리기
손상된 행만 다시 그려요.
- 행 해시
04변경 감지 게이트
변경 없는 프레임은 여기서 멈춰요.
- RLE
05인코딩
셀 3,200개가
%c스팬 149개로 바뀌어요. - console.log
06출력
프레임은 최소 66ms 간격으로 덧붙여요.
clear() + log()70.6% 빈 화면log(), appended1.0% 빈 화면%c 인수서버에서 라우트 렌더링
라우트와 비동기 컴포넌트를 서버에서 렌더링하려면 runtime = "server"를 내보내세요. 브라우저는 앱 대신 21kB(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}- 부분 프리렌더링모든 정적 라우트의 첫 프레임은 HTML에 담겨 전달돼요. JavaScript가 로드되기 전에 콘솔이 그려져요.
- 미들웨어
middleware.ts는 일치하는 요청 전에NextRequest,NextResponse,config.matcher를 사용해 실행돼요. - 캐싱
revalidate,unstable_cache,revalidateTag는 stale-while-revalidate 방식으로 라우트 핸들러와 데이터를 캐시해요. - 배포 어댑터
text build --adapter는static,bun,vercel또는cloudflare를 대상으로 해요. 서버에서 렌더링된 라우트에는bun또는text start가 필요해요.
터미널과 에이전트에서도 실행
DevToolstext dev
Turbolog는 console.log 한 번으로 각 프레임을 %c 스팬으로 기록해요.
터미널text run
text run은 동일한 App Router 앱을 트루컬러 ANSI로 렌더링하고 라우트 핸들러를 프로세스 안에서 실행해요.
코딩 에이전트text mcp
에이전트는 MCP로 라우트를 탐색하고, 키를 누르고, 각 프레임을 일반 텍스트로 읽어요.
에디터, 린트, 테스트 도구
DevTools 확장 프로그램
컴포넌트 트리, 프레임 검사기, 프레임별 타임라인이 있는 패널을 추가해요.
Text.js 패널VS Code
코드 옆에 프레임 미리보기를 표시하고 App Router 파일의 기본 구조를 생성해요.
⌘K VESLint
콘솔 컴포넌트의 DOM 태그, 텍스트 안의 박스, Menlo에 없는 글리프를 찾아내요.
eslint-plugin-textjs테스트
어떤 테스트 러너에서든 화면 밖에서 렌더링하고, 키를 누르고, lastFrame()으로 검증하세요.
오류 코드
TX 코드가 있는 오류와 경고는 해결 방법을 설명하는 페이지로 연결돼요.
콘솔 REPL
콘솔 프롬프트에서 실행 중인 앱을 일시 정지하고, 크기를 조절하고, 와이어프레임으로 표시하고, 복사하세요.
window.text오른쪽에서 왼쪽으로
유니코드 양방향 알고리즘을 구현하고 BidiTest.txt 테스트 770,241개를 모두 통과해요.
FIGlet 글꼴
.flf 파일을 파싱하고 figlet 바이너리에서 기록한 출력 273개와 일치해요.