@zyntra-js/cli
v0.2.82
Published
CLI for ZyntraJS type-safe client generation
Maintainers
Readme
@zyntra-js/cli
The official Command-Line Interface (CLI) for the ZyntraJS framework. Automate project scaffolding, generate production-ready CRUD code from your Prisma schema, run the dev server, and generate API documentation — all from one tool.
npx @zyntra-js/cli@latest <command>Table of Contents
- Quick Start
- Commands Overview
- zyntra init
- zyntra dev
- zyntra generate feature (Auto CRUD Generation)
- zyntra generate schema
- zyntra generate docs
- Generated Code Structure
- Working with Relationships
- Global Options
Quick Start
# 1. Create a new project
npx @zyntra-js/cli@latest init my-app
# 2. Enter the project
cd my-app
# 3. Start the dev server
npx @zyntra-js/cli dev
# 4. Generate a feature from your Prisma model
npx @zyntra-js/cli generate feature user --schema prisma:UserCommands Overview
| Command | Description |
|---------|-------------|
| zyntra init [name] | Create a new ZyntraJS project with interactive setup |
| zyntra dev | Start the development server with hot-reload |
| zyntra generate feature [name] | Scaffold a full CRUD feature from Prisma models |
| zyntra generate schema | Generate type-safe client schema from your router |
| zyntra generate docs | Generate OpenAPI specification and interactive playground |
zyntra init
Scaffolds a new, production-ready ZyntraJS project from scratch with an interactive setup wizard.
npx @zyntra-js/cli@latest init my-appOptions
| Option | Description |
|--------|-------------|
| --force | Skip confirmation prompts and overwrite existing files |
| --pm, --package-manager <manager> | Package manager: npm, yarn, pnpm, bun |
| --template <template> | Use a specific starter (e.g., starter-nextjs, starter-express-rest-api) |
| -f, --framework <framework> | Target framework: nextjs, vite, nuxt, sveltekit, remix, astro, express, tanstack-start |
| --features <features> | Comma-separated features: store, jobs, mcp, logging, telemetry |
| --database <database> | Database provider: none, postgresql, mysql, sqlite |
| --orm <orm> | ORM provider: prisma, drizzle |
| --no-git | Skip git repository initialization |
| --no-install | Skip automatic dependency installation |
| --no-docker | Skip Docker Compose setup |
Examples
# Interactive mode (recommended)
npx @zyntra-js/cli@latest init my-app
# Fully automated setup
npx @zyntra-js/cli@latest init my-app \
--framework nextjs \
--database postgresql \
--orm prisma \
--features store,jobs,logging \
--pm bunFor more details, see the zyntra init documentation.
zyntra dev
Starts the development server with hot-reload, framework integration, and an interactive dashboard.
npx @zyntra-js/cli devOptions
| Option | Description |
|--------|-------------|
| --framework <type> | Framework type: nextjs, vite, nuxt, sveltekit, remix, astro, express, tanstack-start, generic |
| --output <dir> | Output directory for generated client files (default: src/) |
| --port <number> | Port for the dev server (default: 3000) |
| --cmd <command> | Custom command to start dev server |
| --no-framework | Disable framework dev server (Zyntra only) |
| --no-interactive | Disable interactive mode |
| --docs-output <dir> | Output directory for OpenAPI docs (default: ./src/docs) |
Examples
# Auto-detect framework and start in interactive mode
npx @zyntra-js/cli dev
# Specify framework and port
npx @zyntra-js/cli dev --framework nextjs --port 4000
# Zyntra-only mode (no framework dev server)
npx @zyntra-js/cli dev --no-frameworkFor more details, see the zyntra dev documentation.
zyntra generate feature
The most powerful command in the CLI. Automatically generates a complete CRUD feature from your Prisma schema — including controllers, procedures, repositories, and interfaces — all following production-ready patterns with full JSDoc documentation.
npx @zyntra-js/cli generate feature [name] --schema prisma:<ModelName>Options
| Option | Description |
|--------|-------------|
| [name] | Feature name (e.g., user, product). If omitted, runs in interactive mode |
| --schema <value> | Generate from a schema provider (e.g., prisma:User, prisma:Post) |
Usage Modes
Interactive Mode (recommended for first use)
npx @zyntra-js/cli generate featureThe interactive wizard will:
- Ask for the feature name
- Detect your Prisma schema automatically
- List all available models for you to choose
- Generate the complete CRUD code
Direct Mode
# Generate a "product" feature from the Prisma "Product" model
npx @zyntra-js/cli generate feature product --schema prisma:Product
# Generate a "user" feature from the Prisma "User" model
npx @zyntra-js/cli generate feature user --schema prisma:User
# Generate an empty feature (no Prisma)
npx @zyntra-js/cli generate feature notificationWhat Gets Generated
When you run generate feature product --schema prisma:Product, the CLI creates:
src/features/product/
├── controllers/
│ └── product.controller.ts # REST endpoints with JSDoc + error handling
├── procedures/
│ └── product.procedure.ts # Business logic layer with validation
├── repositories/
│ └── product.repository.ts # Data access class with PrismaClient
├── product.interfaces.ts # Zod schemas + TypeScript types
└── index.ts # Barrel exportsExample: From Prisma Schema to Full API
Given this Prisma model:
model Product {
id String @id @default(cuid())
name String
description String?
price Float
inStock Boolean @default(true)
categoryId String
category Category @relation(fields: [categoryId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Running:
npx @zyntra-js/cli generate feature product --schema prisma:ProductGenerates the following files:
product.interfaces.ts
import { z } from "zod";
/**
* @description Zod schema for creating a new Product.
*/
export const CreateProductBodySchema = z.object({
name: z.string(),
description: z.string().nullable(),
price: z.number(),
categoryId: z.string(),
});
/**
* @description Zod schema for updating an existing Product.
*/
export const UpdateProductBodySchema = z.object({
name: z.string().optional(),
description: z.string().nullable().optional(),
price: z.number().optional(),
categoryId: z.string().optional(),
});
export type CreateProductBody = z.infer<typeof CreateProductBodySchema>;
export type UpdateProductBody = z.infer<typeof UpdateProductBodySchema>;Note: The
id,createdAt,updatedAtfields are automatically excluded (auto-generated). Thecategoryrelation field is excluded — only the scalarcategoryIdforeign key is included.
repositories/product.repository.ts
import { PrismaClient, Product } from "@prisma/client";
import { CreateProductBody, UpdateProductBody } from "../product.interfaces";
/**
* @class ProductRepository
* @description Centralizes all database operations for the Product entity using Prisma.
*/
export class ProductRepository {
private db: PrismaClient;
constructor(db: PrismaClient) {
this.db = db;
}
async list(): Promise<Product[]> { /* ... */ }
async getById(id: string): Promise<Product | null> { /* ... */ }
async create(data: CreateProductBody): Promise<Product> { /* ... */ }
async update(id: string, data: UpdateProductBody): Promise<Product> { /* ... */ }
async delete(id: string): Promise<Product> { /* ... */ }
}procedures/product.procedure.ts
/**
* @procedure ProductProcedure
* @description Procedure for managing product operations and data processing.
*
* @example
* ```typescript
* const records = await context.product.findMany()
* const record = await context.product.findUnique("some-id")
* ```
*/
export const productProcedure = zyntra.procedure({
name: 'ProductProcedure',
handler: (_, { context }) => {
return {
product: {
findMany: async () => { /* ... */ },
findUnique: async (id) => { /* ... */ },
create: async (data) => { /* ... */ },
update: async (id, data) => {
// Business Rule: Check if product exists before updating.
const productExists = await context.database.product.findUnique({
where: { id },
});
if (!productExists) {
throw new Error('Product not found');
}
// ...
},
delete: async (id) => { /* ... */ },
},
};
},
});controllers/product.controller.ts
/**
* @const productController
* @description
* Controller for managing product-related operations, including listing, creating,
* updating, and deleting products.
*/
export const productController = zyntra.controller({
name: "product",
path: "/product",
actions: {
list: zyntra.query({ /* GET /product */ }),
getById: zyntra.query({ /* GET /product/:id */ }),
create: zyntra.mutation({ /* POST /product */ }),
update: zyntra.mutation({ /* PUT /product/:id with try/catch */ }),
delete: zyntra.mutation({ /* DELETE /product/:id with try/catch */ }),
},
});After Generating
Register the controller in your router:
// src/zyntra.ts
import { productController } from "./features/product";
const router = zyntra
.router()
.controller(productController);Working with Relationships
The CLI correctly handles Prisma relationships when generating code:
What Gets Included
- Scalar fields (
String,Int,Boolean, etc.) — included in schemas - Foreign key fields (
authorId,categoryId) — included in schemas as normal fields - Auto-generated fields (
id,createdAt,updatedAt) — excluded from Create/Update schemas
What Gets Excluded
- Relation object fields (
author User @relation(...)) — excluded from schemas - Relation array fields (
posts Post[]) — excluded from schemas
Example
model Post {
id String @id @default(cuid()) // excluded (auto-generated)
title String // included
content String? // included (nullable)
author User @relation(...) // excluded (relation)
authorId String // included (FK scalar)
tags Tag[] // excluded (relation array)
createdAt DateTime @default(now()) // excluded (auto-generated)
}Generated CreatePostBodySchema:
z.object({
title: z.string(),
content: z.string().nullable(),
authorId: z.string(),
})zyntra generate schema
Generates the type-safe client schema from your Zyntra router for CI/CD or manual builds.
npx @zyntra-js/cli generate schemaOptions
| Option | Description |
|--------|-------------|
| --framework <type> | Framework type |
| --output <dir> | Output directory (default: src/) |
| --watch | Watch for changes and regenerate automatically |
| --docs | Enable automatic OpenAPI documentation generation |
| --docs-output <dir> | Output directory for OpenAPI docs (default: ./src/docs) |
Examples
# One-time schema generation
npx @zyntra-js/cli generate schema
# Watch mode for development
npx @zyntra-js/cli generate schema --watch
# With OpenAPI docs
npx @zyntra-js/cli generate schema --watch --docszyntra generate docs
Generates an OpenAPI 3.0 specification and optionally an interactive API playground powered by Scalar UI.
npx @zyntra-js/cli generate docsOptions
| Option | Description |
|--------|-------------|
| --output <dir> | Output directory for the OpenAPI spec (default: ./src) |
| --ui | Generate a self-contained HTML file with interactive Scalar UI |
Examples
# Generate OpenAPI JSON spec
npx @zyntra-js/cli generate docs
# Generate spec + interactive playground
npx @zyntra-js/cli generate docs --ui
# Custom output directory
npx @zyntra-js/cli generate docs --ui --output ./public/docsGenerated Files
| File | Description |
|------|-------------|
| docs/openapi.json | OpenAPI 3.0.0 specification |
| docs/index.html | Interactive Scalar UI playground (with --ui) |
Generated Code Structure
Every feature generated with --schema follows the same production-ready pattern used across all ZyntraJS starters:
src/features/{feature}/
│
├── {feature}.interfaces.ts # Zod validation schemas + TypeScript types
│ ├── Create{Model}BodySchema # Fields for creation (excludes auto-generated)
│ ├── Update{Model}BodySchema # All fields optional for partial updates
│ ├── Create{Model}Body # TypeScript type inferred from Zod
│ └── Update{Model}Body # TypeScript type inferred from Zod
│
├── repositories/
│ └── {feature}.repository.ts # Data access layer (class-based)
│ └── {Model}Repository # PrismaClient injection, CRUD methods
│
├── procedures/
│ └── {feature}.procedure.ts # Business logic layer
│ └── {model}Procedure # Context injection, validation, error handling
│
├── controllers/
│ └── {feature}.controller.ts # HTTP endpoints
│ └── {model}Controller # REST CRUD with proper response codes
│
└── index.ts # Barrel exports for clean importsArchitecture Flow
HTTP Request → Controller → Procedure (business logic + validation) → Prisma Database
↑
Repository (data access class, available for direct use)Code Quality Features
All generated code includes:
- Full JSDoc documentation —
@description,@param,@returns,@throwson every method - Inline comments —
// Business Logic:,// Business Rule:,// Observation:,// Response: - Error handling —
try/catchon update/delete controllers, existence validation in procedures - Type safety — Zod schemas for request validation, Prisma types for database operations
- Consistent patterns — Same structure used across all 6 official ZyntraJS starters
Global Options
| Option | Description |
|--------|-------------|
| --debug | Enable debug mode for detailed logging |
| --version | Show CLI version |
| --help | Show help for any command |
# Enable debug logging for any command
npx @zyntra-js/cli generate feature --debug
# Show help
npx @zyntra-js/cli --help
npx @zyntra-js/cli generate feature --helpContributing
Contributions are welcome! Please see the main CONTRIBUTING.md file for details on how to get started.
License
This package is licensed under the MIT License.
