@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 +7 -0
- package/README.md +46 -49
- package/docs/cli.md +154 -0
- package/package.json +1 -1
- package/src/cli/index.ts +47 -2
- package/tests/cli.test.ts +3 -0
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
|
|
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 **
|
|
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
|
-
##
|
|
19
|
+
## Getting Started (Quick Start)
|
|
20
20
|
|
|
21
|
-
|
|
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
|
-
|
|
25
|
+
bunx @martel/calyx new my-app
|
|
25
26
|
```
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
### 2. Run the Development Server (Watch Mode)
|
|
29
|
+
```bash
|
|
30
|
+
cd my-app
|
|
31
|
+
bun run start:dev
|
|
32
|
+
```
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
##
|
|
57
|
+
## Manual Installation
|
|
41
58
|
|
|
42
|
-
|
|
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
|
-
|
|
47
|
-
@
|
|
48
|
-
|
|
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
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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** | **
|
|
89
|
-
| **Raw Route Throughput** | **
|
|
90
|
-
| **Lifecycle Pipeline (Guards/Pipes)** | **
|
|
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
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":
|
|
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
|
|