The original Greek word "model" means "misshapen ball of clay", and I try to think about that every time I go in front of the camera. - Derek Zoolander
_____ _
/ ____| |
| | | | __ _ _ _
| | | |/ _` | | | |
| |____| | (_| | |_| |
\_____|_|\__,_|\__, |
__/ |
|___/
📚 Full Documentation | Getting Started | NPM Package
Clay is a template-focused code generator that transforms JSON models into actual code using Handlebars templates, shell commands, and file operations. Built with TypeScript for type safety and reliability.
# Install globally
npm install -g clay-generator
# Initialize a project
clay init
# Generate code
clay generate ./clay/model.json ./output- ✅ Template-Based Generation - 47+ Handlebars helpers for flexible code generation
- ✅ Type-Safe - Built with TypeScript for reliability
- ✅ Model-Driven - Define your domain once, generate everywhere
- ✅ Watch Mode - Auto-regenerate on model changes
- ✅ AI-Powered - MCP server for Claude & GitHub Copilot
- Getting Started - Installation, setup, and your first project
- Philosophy - Benefits and trade-offs of code generation
- Models - Define domain models in JSON with mixins and includes
- Generators - Configure generation steps and workflows
- Templates - Handlebars templates with 47+ helpers
- AI Integration - MCP server for Claude & Copilot
- CLI Reference - Complete command-line guide
Generate files from Handlebars templates with access to your full model data. Use 47+ built-in helpers for string manipulation, logic, iteration, and more.
Target specific parts of your model for precise generation. Test selectors with the clay test-path command.
Automatically regenerate when models or templates change during development.
MCP server provides type-safe tool calls for Claude and GitHub Copilot, enabling AI-assisted generator development.
Model (clay/model.json):
{
"name": "user-service",
"generators": ["./generators/api"],
"model": {
"types": [
{
"name": "User",
"fields": [
{ "name": "id", "type": "string" },
{ "name": "email", "type": "string" }
]
}
]
}
}Template (generators/api/templates/model.js):
class {{pascalCase name}} {
constructor(data) {
{{#each fields}}
this.{{name}} = data.{{name}};
{{/each}}
}
}Generated (src/models/user.model.js):
class User {
constructor(data) {
this.id = data.id;
this.email = data.email;
}
}clay generate [model] [output] # Generate code
clay clean [model] [output] # Remove generated files
clay watch [model] [output] # Watch and regenerate
clay test-path <model> <path> # Test JSONPath expressions
clay init [type] [name] # Initialize project or generatorClay includes an MCP server for seamless integration with AI assistants like Claude and GitHub Copilot.
Quick Setup for VS Code:
// .vscode/mcp.json
{
"servers": {
"clay": {
"type": "stdio",
"command": "clay-mcp",
"args": []
}
}
}We welcome contributions! See CONTRIBUTING.md for development setup and guidelines.
- Node.js 14 or higher
- npm 7 or higher
- Clone the repository
git clone https://github.com/morkeleb/clay.git
cd clay- Install dependencies
npm install- Build the project
npm run buildThis compiles TypeScript files from src/ to JavaScript in dist/.
- Link for local development
npm linkThis makes the clay command available globally, pointing to your local development version. Changes to TypeScript files are automatically picked up by the development wrapper script.
Clay is written in TypeScript and uses a smart development workflow that doesn't require constant recompilation:
Development Mode (Recommended)
When you npm link Clay locally, the bin/clay-dev wrapper automatically detects that source files exist and uses ts-node to run TypeScript directly:
# After npm link, just run clay commands normally
clay generate ./my-model.json ./output
# TypeScript files are executed directly via ts-node
# No compilation needed!Production Build
For production or to test the compiled output:
npm run build # Compile TypeScript to dist/
npm run build:watch # Compile and watch for changesnpm run build- Compile TypeScript to JavaScriptnpm run build:watch- Compile and watch for changesnpm run dev- Run Clay with ts-node directlynpm test- Run test suitenpm run test:watch- Run tests in watch modenpm run lint- Check code style and qualitynpm run lint:fix- Auto-fix linting issuesnpm run format- Format all TypeScript files with Prettiernpm run format:check- Check formatting without making changes
clay/
├── src/ # TypeScript source files
│ ├── types/ # Type definitions
│ │ ├── generator.ts # Generator types
│ │ ├── model.ts # Model types
│ │ ├── clay-file.ts # Clay file types
│ │ └── ...
│ ├── command-line.ts # CLI command definitions
│ ├── generator.ts # Generator execution engine
│ ├── model.ts # Model loading and processing
│ ├── template-engine.ts # Handlebars template system
│ └── ...
├── dist/ # Compiled JavaScript (gitignored)
├── test/ # Test files (.js and .test.ts)
├── bin/ # Executable scripts
│ └── clay-dev # Development wrapper
├── index.ts # Entry point
├── tsconfig.json # TypeScript configuration
├── eslint.config.js # ESLint configuration
└── .prettierrc.json # Prettier configuration
Type Definitions
Clay uses comprehensive type definitions for all core concepts. Key types include:
Generator- Generator configuration and stepsClayModel- Model structure with mixins and includesClayFile- .clay file inventory trackingGeneratorStep- Union type for generate/copy/command steps
Strict Mode
The project uses TypeScript strict mode for maximum type safety. When adding new code:
- Avoid
anytypes when possible - Use proper type annotations
- Leverage type guards for discriminated unions
- Use
unknowninstead ofanyfor truly unknown types
IDE Support
TypeScript provides excellent IDE support. VS Code (or similar) will provide:
- Autocomplete for all functions and properties
- Inline type documentation
- Error detection as you type
- Refactoring support
Tests are written in TypeScript using Mocha, Chai, and Sinon:
npm test # Run all tests
npm run test:watch # Run tests in watch modeTest files use .test.ts extension and are located in the test/ directory. The test setup uses ts-node to run TypeScript tests directly.
Linting
npm run lint # Check for issues
npm run lint:fix # Auto-fix issuesESLint is configured with TypeScript support and checks for:
- TypeScript-specific issues
- Code style consistency
- Potential bugs
- Best practices
Formatting
npm run format # Format all files
npm run format:check # Check formattingPrettier ensures consistent code formatting across the project.
- Create a feature branch from
main - Make your changes in TypeScript
- Add tests for new functionality
- Run
npm run lintandnpm run format - Ensure
npm testpasses - Submit a pull request
The npm package includes only the compiled JavaScript in dist/ and the bin wrapper. The TypeScript source is excluded from the published package but available in the GitHub repository.
> clay
Usage: clay [options] [command]
Options:
-V, --version output the version number
-v, --verbose ignore test hook
-h, --help output usage information
Commands:
test-path <model_path> <json_path> test a json-path selector using your model
clean <model_path> <output_path> cleans up the output of the generators
generate <model_path> <output_path> runs the generators
watch <model_path> <output_path> runs the generators on filechanges in the models directory
init [type] [name] initializes the folder with an empty .clay file or a generator
Clay commands follow a simple pattern. Here are quick examples:
# Generate code from model
clay generate <model_path> <output_path>
# Test JSONPath expressions
clay test-path <model_path> "$.model.types[*]"
# Clean generated files
clay clean <model_path> <output_path>
# Watch for changes
clay watch <model_path> <output_path>
# Initialize project or generator
clay init
clay init generator my-generator→ See detailed command documentation
For continuous development, use watch mode to automatically regenerate when files change. See the CLI documentation for details.
→ See Complete Model Documentation
Clay uses structured JSON models with support for includes and mixins. Models define your domain structure and specify which generators to run.
→ See Complete Generator Documentation
Generators define steps to generate files, run commands, or copy existing files. Each generator runs in the order defined.
→ See Complete Template & Helper Documentation
Clay uses Handlebars templates with custom helpers for case conversion, pluralization, and more. Templates support partials for reusable code snippets.
A typical Clay project structure:
clay/
├── model.json # Your domain model
├── generators/ # Custom generators
│ └── my-generator/
│ ├── generator.json # Generator configuration
│ ├── templates/ # Handlebars templates
│ └── partials/ # Reusable template parts
└── mixins/ # Model transformation functions
→ Complete Project Structure Guide
Clay integrates with GitHub Copilot through the MCP server. See the AI Integration section above for setup.
→ Complete Copilot Integration Guide
- ✅ Casing helpers (camelCase, pascalCase, etc.)
- ✅ Increment helper for indexes
- ✅ Pretty output with chalk
- ✅ Node module generator loading
- ✅ Built-in watch support
- ✅ Clean command
- ✅ .clay file inventory tracking
- ✅ Generator validation
- Model validations
- Dry run option
- Template system regression tests
- Directory clearing option
We welcome contributions! See CONTRIBUTING.md for guidelines.
MIT