Project Structure

The app/ directory, text.config.ts and the text CLI.

Folders in app/ define routes, and special files define the UI for each route.

Folders

FolderPurpose
appRoutes, layouts and route handlers
libShared modules, not routed
publicStatic assets

Routing files

FilePurpose
layout.tsxShared UI for a segment
page.tsxA routable screen
loading.tsxSuspense fallback
error.tsxError boundary
not-found.tsxUnmatched URLs
route.tsAPI endpoint
app/├── layout.tsx            → shared shell├── page.tsx              → /├── sessions/│   ├── page.tsx          → /sessions│   └── [id]/page.tsx     → /sessions/:id└── api/health/route.ts   → GET /api/health

Dynamic routes

FolderURLparams
[id]/sessions/42{ id: "42" }
[...slug]/docs/a/b{ slug: ["a", "b"] }

text.config.ts

text.config.tsts
import { defineConfig } from "@textjs/app";export default defineConfig({  title: "Acme",  viewport: { width: 120, height: 36, theme: "geistDark" },  hints: [{ keys: "↑ ↓", label: "count" }],});
OptionDefaultDescription
title""Page and FocusPad title
viewportfit console, else 120×36responsive (default true), fallback width × height, theme
hints[]Two or three keys shown on the page's FocusPad
actionpress <first hint>What to do once focused, e.g. "type a prompt"
devIndicatorstrueIn-console Dev Overlay ([▼])
focusHinttrue"Click the page to use the keyboard" over the console's last row while the page doesn't have focus
rewrites[]Rewrites and proxies
ansi{ cols: 80, rows: 24 }Frame size for curl and terminal clients, or false to serve them HTML
embedfalseBuild the app for other sites to add with one script tag (Embedding, experimental)

CLI

CommandDescription
text devDev server with Fast Refresh
text buildProduction build
text startServe the build and route handlers
text runRender the app in a terminal (Terminal)
text mcpServe the app to coding agents (MCP)
Edit this page on GitHub