Loom
AI-powered JSON Schema document generator with TUI, web viewer and mock server

✨ Features
- 🤖 AI-Powered Schema Generation - Interactive TUI chat interface to generate and update JSON Schema API documentation using LLMs (DeepSeek, OpenAI)
- 🧩 Entity-Centric Modeling - Manage reusable entity schemas in
docs/entities and reference them in endpoint schemas via x-entity-ref
- 📚 Modern Web Viewer - React-based SPA for browsing modules, endpoints, and entities with interactive schema rendering
- ⚡ Mock Server - Dynamic mock API server that generates realistic test data based on JSON Schema
- 🖥️ In-Chat Service Control - Start/stop/restart mock server and web viewer directly inside TUI (
/mock, /view)
- 🗂️ Manifest Indexing - Built-in manifest rebuild command for dependency/index consistency (
loom manifest rebuild)
- ⬆️ Auto Update Prompt - On startup, Loom checks npm for a newer version and can upgrade automatically after confirmation
- 🔧 TypeScript First - Fully typed with modern TypeScript architecture
📦 Installation
Prerequisites
- Node.js ≥ 18.0.0
- npm or yarn
- DeepSeek API key (for chat functionality)
Global Installation
npm install -g loom
yarn global add loom
Local Development
git clone <repository-url>
cd loom
npm install
npm run build:all
⚙️ Configuration
Configuration File
Loom uses a global config file (no .env dependency).
Default global config path:
- macOS/Linux:
~/.loom/config.json
- Windows:
%APPDATA%/loom/config.json
Optional override:
LOOM_CONFIG=/custom/path/config.json
When you run loom chat for the first time, it will guide you to create/update this global file interactively.
Default chat onboarding values:
provider: deepseek
model: deepseek-chat
baseURL: https://api.deepseek.com/v1
apiKey: required, must be entered by user
You can also create the global config manually:
{
"outDir": "docs",
"llm": {
"provider": "deepseek",
"model": "deepseek-chat",
"baseURL": "https://api.deepseek.com/v1",
"apiKey": "your_deepseek_api_key",
"temperature": 0.7,
"maxTokens": 2000
},
"serve": {
"port": 3000,
"host": "0.0.0.0"
},
"mock": {
"port": 3001,
"host": "0.0.0.0"
}
}
docs/ remains in each project directory (--dir) and is not moved to global storage.
🚀 Quick Start
1. Generate API Documentation
loom chat
loom chat --dir ./my-api-project
In loom chat, you can also control local services:
/mock, /mock stop, /mock restart [port]
/view, /view stop, /view restart [port]
2. View Documentation
loom view
loom view --port 8080
3. Start Mock Server
loom mock
loom mock --port 8081
4. Combined Service (Recommended)
loom serve
5. Upgrade Loom
loom upgrade
Loom also checks npm for updates when you run commands.
If a newer version is found, you can confirm and let Loom auto-upgrade.
📖 Usage Guide
loom chat
Interactive terminal UI for generating JSON Schema documents through AI conversation.
loom chat [options]
Options:
-d, --dir <path> Target project directory (default: current directory)
-h, --help Display help
Example Workflow:
- Run
loom chat
- Describe your API endpoints in natural language
- AI generates JSON Schema with proper structure
- Schema files are saved to
docs/ directory (configurable)
Built-in chat commands:
- Input tip:
Enter to send, Shift+Enter or Alt+Enter for newline
/help — Show command help
/reset — Reset conversation history
/list — List generated schema files
/mock, /mock stop, /mock restart [port] — Manage mock server
/view, /view stop, /view restart [port] — Manage web viewer
/abort — Abort current request
/exit — Exit Loom
loom view
Modern web-based documentation viewer with React SPA interface.
loom view [options]
Options:
-p, --port <number> Port number (default: 3000)
-d, --dir <path> Target project directory (default: current directory)
-h, --help Display help
Features:
- 📁 Module browsing with endpoint counts
- 🧩 Entity browsing from
docs/entities
- 🔍 Real-time search across modules and endpoints
- 📊 Swagger-like schema table viewer for all request/response sections (query params, path params, headers, body)
- 🔗
x-entity-ref auto-resolve in endpoint request/response rendering
- 🎨 Clean, responsive UI with dark sidebar
- 🔗 Direct links to specific endpoints
loom mock
Dynamic mock API server that generates realistic data based on JSON Schema.
loom mock [options]
Options:
-p, --port <number> Port number (default: 3001)
-d, --dir <path> Target project directory (default: current directory)
-h, --help Display help
Features:
- 🚀 Automatic route registration from JSON Schema files
- 🎲 Smart mock data generation using mock-json-schema
- 📡 Support for all HTTP methods (GET, POST, PUT, DELETE, PATCH)
- 🔧 Configurable response status codes and schemas
loom serve
Combined service that runs both web viewer and mock server together.
loom serve [options]
Options:
-p, --port <number> Port number (default: 3000)
-d, --dir <path> Target project directory (default: current directory)
-h, --help Display help
URL Structure:
http://localhost:3000/ - Web documentation viewer
http://localhost:3000/api/docs - Documentation API
http://localhost:3000/api/schemas - Schema file API
http://localhost:3000/api/entities - Entity file API
http://localhost:3000/mock/... - Mock API endpoints
loom manifest rebuild
Rebuild docs manifest index file (.loom-manifest.json) for dependency/index consistency.
loom manifest rebuild [options]
Options:
-d, --dir <path> Target project directory (default: current directory)
-h, --help Display help
loom upgrade
Upgrade loom to the latest npm version.
loom upgrade
📝 JSON Schema Format
Loom uses a custom JSON Schema format optimized for API documentation:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Authentication API",
"description": "User authentication endpoints",
"version": "1.0.0",
"endpoints": [
{
"path": "/api/auth/login",
"method": "POST",
"summary": "User login",
"description": "Authenticate user with credentials",
"tags": ["auth"],
"request": {
"headers": {
"Content-Type": { "type": "string", "enum": ["application/json"] }
},
"body": {
"type": "object",
"properties": {
"username": { "type": "string" },
"password": { "type": "string" }
},
"required": ["username", "password"]
}
},
"response": {
"200": {
"type": "object",
"properties": {
"token": { "type": "string" },
"user": { "type": "object" }
}
},
"400": {
"type": "object",
"properties": {
"error": { "type": "string" }
}
}
}
}
]
}
Schema Structure
- title: API module title
- description: Module description
- endpoints: Array of API endpoint definitions
- endpoint.path: URL path (supports path parameters)
- endpoint.method: HTTP method (GET, POST, PUT, DELETE, PATCH)
- endpoint.request: Optional request schema (headers, params, query, body)
- endpoint.response: Response schemas keyed by status code
🧩 Entity Schema & References
Loom supports reusable entity schemas in:
docs/entities/*.entity.schema.json
Example entity file:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "User",
"description": "Reusable user entity",
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"email": { "type": "string", "format": "email" }
},
"required": ["id", "name", "email"]
}
In endpoint schemas, reference an entity with x-entity-ref:
{
"user": {
"x-entity-ref": {
"entity": "User",
"pick": ["id", "name", "email"]
}
}
}
Supported forms:
- String form:
"x-entity-ref": "User"
- Object form:
"x-entity-ref": { "entity": "User", "pick": ["id", "name"] }
🏗️ Project Structure
loom/
├── src/
│ ├── agents/ # AI agent system with tool calling
│ │ ├── core/ # Agent core logic
│ │ └── memory/ # Conversation memory management
│ ├── llm/ # LLM client (DeepSeek, OpenAI)
│ │ ├── client.ts # Streaming LLM client
│ │ └── config.ts # LLM configuration
│ ├── tools/ # Tool system for agent
│ │ ├── schema-gen.ts # Schema generation tools
│ │ ├── schema-validate.ts # Schema validation tools
│ │ ├── file-ops.ts # Schema file operations tools
│ │ ├── entity-file-ops.ts # Entity file operations tools
│ │ └── entity-workflow.ts # Entity impact/sync/validate tools
│ ├── tui/ # Terminal UI (chat interface)
│ │ ├── app.tsx # Main TUI application
│ │ └── components/ # React components for TUI
│ ├── view/ # Web documentation viewer
│ │ ├── server.ts # Fastify web server
│ │ ├── routes/ # API routes
│ │ ├── frontend/ # React SPA frontend
│ │ └── public/ # Static assets
│ ├── mocks/ # Mock server
│ │ ├── server.ts # Mock server implementation
│ │ ├── router.ts # Dynamic route registration
│ │ └── generator.ts # Mock data generation
│ ├── shared/ # Shared utilities
│ │ ├── config.ts # Configuration loader
│ │ ├── entity-utils.ts # Entity read/write/reference helpers
│ │ ├── manifest-utils.ts # Manifest index builder
│ │ ├── schema-entity-resolver.ts # x-entity-ref resolver for viewer APIs
│ │ ├── types.ts # TypeScript definitions
│ │ └── logger.ts # Logging utilities
│ ├── serve.ts # Combined viewer + mock server
│ └── index.ts # CLI entry point
├── docs/ # Generated schema files
├── scripts/ # Build scripts
├── dist/ # Compiled output
└── package.json
🛠️ Development
Building the Project
npm run build
npm run build:view
npm run build:all
Development Mode
npm run dev
npm run dev:view
Adding New Features
- New LLM Provider: Extend
src/llm/config.ts and src/llm/client.ts
- New Agent Tool: Add under
src/tools/ and register in src/agents/core/agent.ts
- UI Component: Add to
src/view/frontend/components/
- API Endpoint: Add to
src/view/routes/ or src/mocks/router.ts
📦 Publishing to npm
For maintainers, to publish a new version to npm registry:
npm login
npm version patch
npm run build:all
npm publish
npm publish --dry-run
The package includes:
- Compiled JavaScript in
dist/
- TypeScript definitions
- Pre-built React frontend bundle
- CLI executable (
loom)
Package configuration:
prepack script ensures fresh build before packaging
.npmignore excludes source files and development artifacts
- All runtime dependencies are correctly specified
📋 Changelog
v0.1.6
- Added: Mock view / Mock edit pages for each endpoint, accessible from the module list
- Added: Sidecar
<name>.mock.json storage for hand-written mock responses (one active override per endpoint)
- Added: Mock server now responds with the override's HTTP status code (e.g. saving a 400 mock makes
/mock/<path> return real HTTP 400)
- Added: Status code switcher in Mock view/edit, marking which statuses already have a saved override
- Added: cURL example block on Mock view, generated from the endpoint's
request schema (path params, query, headers, body all filled with samples)
- Added: Mock.js expression support inside saved mock bodies (
@cname, @integer(1,100), 'list|1-5': [...] etc.) — templates are stored as-is and expanded on each request
- Removed: Inline "Mock Testing" section from the endpoint detail page (superseded by the dedicated Mock pages)
v0.1.4
- Fixed: Query parameters, path parameters, and headers for GET endpoints now display correctly in the Web Viewer
- Improved: All request/response sections use a consistent Swagger-like table view (SchemaTableViewer) with type badges, constraints, and expand/collapse support
- Fixed: Duplicate
setNotFoundHandler error when starting the Web Viewer (loom view) or combined server (loom serve)
- Removed: Broken
@stoplight/json-schema-viewer dependency (incompatible with React 19)
🤝 Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m 'Add amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
Development Guidelines
- Use TypeScript with strict mode
- Follow existing code style and patterns
- Add tests for new functionality
- Update documentation as needed
📄 License
This project is licensed under the ISC License - see the LICENSE file for details.
🙏 Acknowledgments
📞 Support
- Issues: GitHub Issues
- Documentation: This README and code comments
- Questions: Open an issue or discussion
Made with ❤️ by the Loom team