@martel/calyx 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [1.2.0](https://github.com/bmartel/calyx/compare/v1.1.0...v1.2.0) (2026-07-01)
2
+
3
+
4
+ ### Features
5
+
6
+ * enhance CLI new command with Dockerfile and Bun-native lifecycle scripts ([8037a35](https://github.com/bmartel/calyx/commit/8037a35a771e222398168b19cb77ad9ccfa2c49a))
7
+
1
8
  # [1.1.0](https://github.com/bmartel/calyx/compare/v1.0.0...v1.1.0) (2026-07-01)
2
9
 
3
10
 
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Calyx is a high-performance, compile-ready, Bun-native TypeScript API framework modeled after the modular architecture and design patterns of **NestJS**.
4
4
 
5
- It provides 100% conceptual and syntax compatibility, letting developers easily migrate NestJS applications to a native Bun runtime for **~2.5x higher throughput** and **3.5x lower latency**, with the option to compile the server directly into a single self-contained binary file.
5
+ It provides 100% conceptual and syntax compatibility, letting developers easily migrate NestJS applications to a native Bun runtime for **up to 4.7x higher throughput** and **5.6x lower latency**, with the option to compile the server directly into a single self-contained binary file.
6
6
 
7
7
  ---
8
8
 
@@ -10,71 +10,67 @@ It provides 100% conceptual and syntax compatibility, letting developers easily
10
10
 
11
11
  * **⚡ Blazing Fast**: Engineered natively on `Bun.serve`, utilizing a fast radix routing engine and optimized request lifecycle executions.
12
12
  * **🧩 NestJS Decorators Compatibility**: Direct mappings of `@Module()`, `@Injectable()`, `@Controller()`, `@UseGuards()`, `@UseInterceptors()`, `@UsePipes()`, and `@UseFilters()`.
13
- * **📦 High Performance DI**: Fully featured Dependency Injection container with circular dependency protection, supporting custom (`useValue`/`useClass`/`useFactory`) and dynamic modules with **29x lower bootstrapping overhead**.
13
+ * **📦 High Performance DI**: Fully featured Dependency Injection container with circular dependency protection, supporting custom (`useValue`/`useClass`/`useFactory`) and dynamic modules with **18x lower bootstrapping overhead**.
14
14
  * **🛡️ Complete Request Lifecycle**: Clean request pipelines with Guards, Interceptors, Pipe transforms (with metadata), and target exception Filters.
15
15
  * **🚀 Binary Compilation**: Compiles down to a single standalone executable binary with zero external runtime dependencies using `bun build --compile`.
16
16
 
17
17
  ---
18
18
 
19
- ## Installation
19
+ ## Getting Started (Quick Start)
20
20
 
21
- Initialize your project and install Calyx with your package manager:
21
+ The easiest way to get started with Calyx is using the Bun-native CLI tool:
22
22
 
23
+ ### 1. Scaffold a New Project
23
24
  ```bash
24
- bun add @martel/calyx reflect-metadata
25
+ bunx @martel/calyx new my-app
25
26
  ```
26
27
 
27
- Ensure your `tsconfig.json` has legacy decorators enabled:
28
+ ### 2. Run the Development Server (Watch Mode)
29
+ ```bash
30
+ cd my-app
31
+ bun run start:dev
32
+ ```
28
33
 
29
- ```json
30
- {
31
- "compilerOptions": {
32
- "experimentalDecorators": true,
33
- "emitDecoratorMetadata": true
34
- }
35
- }
34
+ ### 3. Generate Components
35
+ Generate modules, controllers, or service providers with automatic parent module registration:
36
+ ```bash
37
+ bunx @martel/calyx g controller users
38
+ bunx @martel/calyx g service users
39
+ ```
40
+
41
+ ### 4. Build and Compile Standalone Binary
42
+ Calyx compiles your entire application into a single self-contained binary file with zero dependencies:
43
+ ```bash
44
+ bun run build:compile
45
+ ./dist/server
46
+ ```
47
+
48
+ ### 5. Deploy with Docker
49
+ Run your compiled binary in a secure, minimal multi-stage Docker container (under **40MB** total image size, containing no `node_modules` or runtime dependencies):
50
+ ```bash
51
+ docker build -t my-app .
52
+ docker run -p 3000:3000 my-app
36
53
  ```
37
54
 
38
55
  ---
39
56
 
40
- ## Quick Start
57
+ ## Manual Installation
41
58
 
42
- ```typescript
43
- import 'reflect-metadata';
44
- import { Module, Injectable, Controller, Get, Query, UseGuards, CanActivate, ExecutionContext, VerdantFactory } from '@martel/calyx';
59
+ If you prefer to set up Calyx manually in an existing project:
45
60
 
46
- // 1. Define a Guard
47
- @Injectable()
48
- class AuthGuard implements CanActivate {
49
- canActivate(context: ExecutionContext): boolean {
50
- const req = context.switchToHttp().getRequest<Request>();
51
- return req.headers.get('Authorization') === 'secret-token';
52
- }
53
- }
61
+ ```bash
62
+ bun add @martel/calyx reflect-metadata
63
+ ```
54
64
 
55
- // 2. Define a Controller
56
- @Controller('items')
57
- class ItemsController {
58
- @Get()
59
- @UseGuards(AuthGuard)
60
- getItems(@Query('limit') limit?: string) {
61
- return { data: ['item1', 'item2'], limit: limit ? Number(limit) : 10 };
62
- }
63
- }
65
+ Ensure your `tsconfig.json` has legacy decorators enabled:
64
66
 
65
- // 3. Define a Module
66
- @Module({
67
- controllers: [ItemsController],
68
- })
69
- class AppModule {}
70
-
71
- // 4. Bootstrap Server
72
- async function bootstrap() {
73
- const app = await CalyxFactory.create(AppModule);
74
- await app.listen(3000);
75
- console.log('Calyx application is running on port 3000');
67
+ ```json
68
+ {
69
+ "compilerOptions": {
70
+ "experimentalDecorators": true,
71
+ "emitDecoratorMetadata": true
72
+ }
76
73
  }
77
- bootstrap();
78
74
  ```
79
75
 
80
76
  ---
@@ -85,9 +81,9 @@ Measured using process-isolated `autocannon` benchmarks (100 connections, 8s, no
85
81
 
86
82
  | Benchmark | Calyx (Bun Native) | NestJS (Express on Bun) | Speedup | Latency Improvement |
87
83
  | :--- | :--- | :--- | :--- | :--- |
88
- | **DI Bootstrapping** | **7.81 μs** | 227.56 μs | **~29x faster** | N/A |
89
- | **Raw Route Throughput** | **59,408 req/sec** | 23,148 req/sec | **2.57x faster** | **3.5x lower** (1.10ms vs 3.88ms) |
90
- | **Lifecycle Pipeline (Guards/Pipes)** | **25,152 req/sec** | 10,274 req/sec | **2.45x faster** | **2.8x lower** (3.25ms vs 9.28ms) |
84
+ | **DI Bootstrapping** | **11.73 μs** | 220.39 μs | **18.79x faster** | N/A |
85
+ | **Raw Route Throughput** | **63,356 req/sec** | 23,796 req/sec | **2.66x faster** | **3.4x lower** (1.05ms vs 3.61ms) |
86
+ | **Lifecycle Pipeline (Guards/Pipes)** | **47,568 req/sec** | 9,961 req/sec | **4.78x faster** | **5.6x lower** (1.70ms vs 9.57ms) |
91
87
 
92
88
  ---
93
89
 
@@ -95,6 +91,7 @@ Measured using process-isolated `autocannon` benchmarks (100 connections, 8s, no
95
91
 
96
92
  For detailed guides, API reference, and examples, refer to the documentation in the repository:
97
93
 
94
+ * 📖 **[Calyx CLI Reference](file:///e:/code/verdant/docs/cli.md)**: Scaffolding, schematic boilerplate generation, and watch modes.
98
95
  * 📖 **[Dependency Injection & Module System](file:///e:/code/verdant/docs/dependency-injection.md)**: Custom providers, modular structures, and resolution visibility.
99
96
  * 📖 **[Controllers & Routing](file:///e:/code/verdant/docs/controllers.md)**: HTTP request handlers, parameters, redirects, and manual response wrappers.
100
97
  * 📖 **[Request Lifecycle Pipeline](file:///e:/code/verdant/docs/lifecycle.md)**: How Guards, Interceptors, Pipes, and Exception Filters interact.
package/docs/cli.md ADDED
@@ -0,0 +1,154 @@
1
+ # Calyx CLI
2
+
3
+ Calyx CLI is a lightweight, Bun-native command-line utility built to replace the standard Nest CLI. It is written in TypeScript and executes natively using Bun, enabling fast project scaffolding, code generation, hot-reloading dev servers, and single-file bundling.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ The CLI is bundled directly into the `@martel/calyx` package. You can run it on-demand using `bunx`:
10
+
11
+ ```bash
12
+ bunx @martel/calyx --help
13
+ ```
14
+
15
+ To install the CLI globally:
16
+
17
+ ```bash
18
+ bun install -g @martel/calyx
19
+ ```
20
+
21
+ ---
22
+
23
+ ## Core Commands
24
+
25
+ ### 1. `calyx new <project-name>`
26
+ Scaffolds a new, fully configured Calyx application with the recommended folder structure, initializes `tsconfig.json` with decorator metadata settings, and runs `bun install` automatically.
27
+
28
+ ```bash
29
+ calyx new my-awesome-app
30
+ ```
31
+
32
+ #### Generated Project Structure
33
+ ```text
34
+ my-awesome-app/
35
+ ├── src/
36
+ │ ├── app.controller.ts
37
+ │ ├── app.module.ts
38
+ │ ├── app.service.ts
39
+ │ └── main.ts
40
+ ├── package.json
41
+ └── tsconfig.json
42
+ ```
43
+
44
+ ---
45
+
46
+ ### 2. `calyx generate` (or `g`)
47
+ Generates boilerplate files for core Calyx components and automatically registers them in the nearest parent Module (e.g., updating the `controllers` or `providers` metadata array).
48
+
49
+ **Usage:**
50
+ ```bash
51
+ calyx g <schematic> <name>
52
+ ```
53
+
54
+ #### Supported Schematics
55
+
56
+ | Schematic | Shortcut | Description |
57
+ | :--- | :--- | :--- |
58
+ | `module` | `module` | Creates a new module file |
59
+ | `controller` | `controller` | Creates a controller and registers it in the module |
60
+ | `service` | `service` | Creates a service provider and registers it in the module |
61
+
62
+ #### Examples
63
+ ```bash
64
+ # Generate a new users module
65
+ calyx g module users
66
+
67
+ # Generate a new users controller and register it in UsersModule
68
+ calyx g controller users
69
+
70
+ # Generate a new users service provider and register it in UsersModule
71
+ calyx g service users
72
+ ```
73
+
74
+ ---
75
+
76
+ ### 3. `calyx start`
77
+ Runs the application from the entrypoint `src/main.ts`.
78
+
79
+ ```bash
80
+ # Start standard execution
81
+ calyx start
82
+
83
+ # Start dev server with built-in hot reloading (Watch Mode)
84
+ calyx start --watch
85
+ # or shortcut:
86
+ calyx start -w
87
+ ```
88
+
89
+ ---
90
+
91
+ ### 4. `calyx build`
92
+ Bundles the application into a single production file (`dist/main.js`) using Bun's native compiler.
93
+
94
+ ```bash
95
+ calyx build
96
+ ```
97
+
98
+ ---
99
+
100
+ ### 5. `calyx info`
101
+ Displays current environment and system details, including Calyx version, Bun version, and OS.
102
+
103
+ ```bash
104
+ calyx info
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Scaffolding Lifecycle & Deployments
110
+
111
+ When a new project is created with `calyx new`, it is pre-configured with industry-best practices for development, testing, compiling, and container deployment.
112
+
113
+ ### Bun-Native NPM Scripts
114
+ The generated `package.json` includes the following scripts:
115
+
116
+ | Command | Action | Description |
117
+ | :--- | :--- | :--- |
118
+ | `bun run start` | `calyx start` | Starts the production server |
119
+ | `bun run start:dev` | `calyx start --watch` | Runs the server with hot-reloading |
120
+ | `bun run build` | `calyx build` | Bundles TS assets into `dist/main.js` |
121
+ | `bun run build:compile` | `bun build --compile` | Compiles application into a single standalone binary |
122
+ | `bun run test` | `bun test` | Runs the Bun-native test runner |
123
+ | `bun run test:watch` | `bun test --watch` | Runs tests in interactive watch mode |
124
+ | `bun run test:cov` | `bun test --coverage` | Outputs test coverage details |
125
+ | `bun run format` | `bunx prettier --write` | Standardizes format across project files |
126
+
127
+ ### Portability & Production Deployments (Docker)
128
+ Calyx supports high-performance Docker builds out-of-the-box. A multi-stage `Dockerfile` is automatically scaffolded in the root folder.
129
+
130
+ It compiles your TypeScript application into a **single self-contained binary** in the builder stage, and copies *only* the binary into a minimal Alpine linux image:
131
+
132
+ ```dockerfile
133
+ # Multistage build for high performance, portability, and minimal size
134
+ FROM oven/bun:1.1-alpine AS builder
135
+ WORKDIR /app
136
+ COPY package.json bun.lockb* ./
137
+ RUN bun install --frozen-lockfile || bun install
138
+ COPY . .
139
+ RUN bun run build:compile
140
+
141
+ # Production runner (Distroless-style minimal Alpine)
142
+ FROM alpine:latest
143
+ RUN apk --no-cache add ca-certificates
144
+ WORKDIR /app
145
+ COPY --from=builder /app/dist/server ./server
146
+ EXPOSE 3000
147
+ CMD ["./server"]
148
+ ```
149
+
150
+ #### Why This is Optimized for Deployments:
151
+ * **Size:** Under **40MB** total image size (compared to ~300MB+ for standard Node/Nest Docker images).
152
+ * **Security:** Contains **no node_modules, no Bun/Node runtimes, and no source code files** in the final production stage. It only has your single executable.
153
+ * **Speed:** The binary is pre-compiled for production, yielding faster startup times and maximum throughput.
154
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@martel/calyx",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "High-performance Bun-native NestJS-compatible framework",
5
5
  "main": "src/index.ts",
6
6
  "bin": {
package/src/cli/index.ts CHANGED
@@ -109,6 +109,9 @@ function runNew(name: string) {
109
109
  mkdirSync(join(name, 'src'), { recursive: true });
110
110
 
111
111
  // Write package.json
112
+ const isDevMode = existsSync(join(import.meta.dir, '../../package.json'));
113
+ const calyxDependency = isDevMode ? "link:../.." : "^0.1.0";
114
+
112
115
  const packageJson = {
113
116
  name,
114
117
  version: '0.0.1',
@@ -117,10 +120,15 @@ function runNew(name: string) {
117
120
  scripts: {
118
121
  "start": "calyx start",
119
122
  "start:dev": "calyx start --watch",
120
- "build": "calyx build"
123
+ "build": "calyx build",
124
+ "build:compile": "bun build src/main.ts --compile --outfile dist/server",
125
+ "test": "bun test",
126
+ "test:watch": "bun test --watch",
127
+ "test:cov": "bun test --coverage",
128
+ "format": "bunx prettier --write \"src/**/*.ts\""
121
129
  },
122
130
  dependencies: {
123
- "@martel/calyx": "link:../..", // link back to Calyx package parent root for local tests
131
+ "@martel/calyx": calyxDependency,
124
132
  "reflect-metadata": "^0.2.2"
125
133
  }
126
134
  };
@@ -141,6 +149,43 @@ function runNew(name: string) {
141
149
  };
142
150
  writeFileSync(join(name, 'tsconfig.json'), JSON.stringify(tsconfigJson, null, 2));
143
151
 
152
+ // Write Dockerfile
153
+ const dockerfile = `# Multistage build for high performance, portability, and minimal size
154
+ FROM oven/bun:1.1-alpine AS builder
155
+ WORKDIR /app
156
+ COPY package.json bun.lockb* ./
157
+ RUN bun install --frozen-lockfile || bun install
158
+ COPY . .
159
+ RUN bun run build:compile
160
+
161
+ # Production runner (Distroless-style minimal Alpine)
162
+ FROM alpine:latest
163
+ RUN apk --no-cache add ca-certificates
164
+ WORKDIR /app
165
+ COPY --from=builder /app/dist/server ./server
166
+ EXPOSE 3000
167
+ CMD ["./server"]
168
+ `;
169
+ writeFileSync(join(name, 'Dockerfile'), dockerfile);
170
+
171
+ // Write .dockerignore
172
+ const dockerignore = `node_modules
173
+ dist
174
+ .git
175
+ .gitignore
176
+ Dockerfile
177
+ README.md
178
+ `;
179
+ writeFileSync(join(name, '.dockerignore'), dockerignore);
180
+
181
+ // Write .gitignore
182
+ const gitignore = `node_modules
183
+ dist
184
+ *.log
185
+ .env
186
+ `;
187
+ writeFileSync(join(name, '.gitignore'), gitignore);
188
+
144
189
  // Write src/app.service.ts
145
190
  const appService = `import { Injectable } from '@martel/calyx';
146
191
 
package/tests/cli.test.ts CHANGED
@@ -36,6 +36,9 @@ describe('Calyx CLI Integration Tests', () => {
36
36
  expect(existsSync(join(testAppName, 'src/app.module.ts'))).toBe(true);
37
37
  expect(existsSync(join(testAppName, 'src/app.controller.ts'))).toBe(true);
38
38
  expect(existsSync(join(testAppName, 'src/app.service.ts'))).toBe(true);
39
+ expect(existsSync(join(testAppName, 'Dockerfile'))).toBe(true);
40
+ expect(existsSync(join(testAppName, '.dockerignore'))).toBe(true);
41
+ expect(existsSync(join(testAppName, '.gitignore'))).toBe(true);
39
42
  expect(existsSync(join(testAppName, 'node_modules'))).toBe(true);
40
43
  });
41
44