@martel/calyx 1.1.0 → 1.2.1

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,17 @@
1
+ ## [1.2.1](https://github.com/bmartel/calyx/compare/v1.2.0...v1.2.1) (2026-07-01)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * resolve local linked dependency using dynamic relative paths in CLI scaffolding ([979a07b](https://github.com/bmartel/calyx/commit/979a07bd2b01f60215ae77650d6cd620195465d8))
7
+
8
+ # [1.2.0](https://github.com/bmartel/calyx/compare/v1.1.0...v1.2.0) (2026-07-01)
9
+
10
+
11
+ ### Features
12
+
13
+ * enhance CLI new command with Dockerfile and Bun-native lifecycle scripts ([8037a35](https://github.com/bmartel/calyx/commit/8037a35a771e222398168b19cb77ad9ccfa2c49a))
14
+
1
15
  # [1.1.0](https://github.com/bmartel/calyx/compare/v1.0.0...v1.1.0) (2026-07-01)
2
16
 
3
17
 
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.1",
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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  import { spawnSync } from 'child_process';
3
3
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
4
- import { join, dirname } from 'path';
4
+ import { join, dirname, relative, resolve } from 'path';
5
5
 
6
6
  const args = Bun.argv.slice(2);
7
7
  const command = args[0];
@@ -109,6 +109,11 @@ 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
114
+ ? `link:${relative(resolve(name), join(import.meta.dir, '../..')).replace(/\\/g, '/')}`
115
+ : "^0.1.0";
116
+
112
117
  const packageJson = {
113
118
  name,
114
119
  version: '0.0.1',
@@ -117,10 +122,15 @@ function runNew(name: string) {
117
122
  scripts: {
118
123
  "start": "calyx start",
119
124
  "start:dev": "calyx start --watch",
120
- "build": "calyx build"
125
+ "build": "calyx build",
126
+ "build:compile": "bun build src/main.ts --compile --outfile dist/server",
127
+ "test": "bun test",
128
+ "test:watch": "bun test --watch",
129
+ "test:cov": "bun test --coverage",
130
+ "format": "bunx prettier --write \"src/**/*.ts\""
121
131
  },
122
132
  dependencies: {
123
- "@martel/calyx": "link:../..", // link back to Calyx package parent root for local tests
133
+ "@martel/calyx": calyxDependency,
124
134
  "reflect-metadata": "^0.2.2"
125
135
  }
126
136
  };
@@ -141,6 +151,43 @@ function runNew(name: string) {
141
151
  };
142
152
  writeFileSync(join(name, 'tsconfig.json'), JSON.stringify(tsconfigJson, null, 2));
143
153
 
154
+ // Write Dockerfile
155
+ const dockerfile = `# Multistage build for high performance, portability, and minimal size
156
+ FROM oven/bun:1.1-alpine AS builder
157
+ WORKDIR /app
158
+ COPY package.json bun.lockb* ./
159
+ RUN bun install --frozen-lockfile || bun install
160
+ COPY . .
161
+ RUN bun run build:compile
162
+
163
+ # Production runner (Distroless-style minimal Alpine)
164
+ FROM alpine:latest
165
+ RUN apk --no-cache add ca-certificates
166
+ WORKDIR /app
167
+ COPY --from=builder /app/dist/server ./server
168
+ EXPOSE 3000
169
+ CMD ["./server"]
170
+ `;
171
+ writeFileSync(join(name, 'Dockerfile'), dockerfile);
172
+
173
+ // Write .dockerignore
174
+ const dockerignore = `node_modules
175
+ dist
176
+ .git
177
+ .gitignore
178
+ Dockerfile
179
+ README.md
180
+ `;
181
+ writeFileSync(join(name, '.dockerignore'), dockerignore);
182
+
183
+ // Write .gitignore
184
+ const gitignore = `node_modules
185
+ dist
186
+ *.log
187
+ .env
188
+ `;
189
+ writeFileSync(join(name, '.gitignore'), gitignore);
190
+
144
191
  // Write src/app.service.ts
145
192
  const appService = `import { Injectable } from '@martel/calyx';
146
193
 
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