https://github.com/pegasusheavy/ngx-bun
🚀 Angular 19+ SSR adapter for Bun - High-performance server-side rendering with Bun's blazing fast runtime
https://github.com/pegasusheavy/ngx-bun
angular angular-19 angular-cli angular-ssr angular-universal bun hydration nodejs prerendering schematics server-side-rendering ssg ssr static-site-generation typescript web-performance
Last synced: 16 days ago
JSON representation
🚀 Angular 19+ SSR adapter for Bun - High-performance server-side rendering with Bun's blazing fast runtime
- Host: GitHub
- URL: https://github.com/pegasusheavy/ngx-bun
- Owner: pegasusheavy
- License: mit
- Created: 2026-01-03T16:02:27.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-01-19T16:11:39.000Z (about 2 months ago)
- Last Synced: 2026-01-29T20:58:21.142Z (about 1 month ago)
- Topics: angular, angular-19, angular-cli, angular-ssr, angular-universal, bun, hydration, nodejs, prerendering, schematics, server-side-rendering, ssg, ssr, static-site-generation, typescript, web-performance
- Language: TypeScript
- Size: 724 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Codeowners: .github/CODEOWNERS
- Security: .github/SECURITY.md
Awesome Lists containing this project
- awesome-angular - ngx-bun - High-performance SSR/SSG adapter for Angular 19+ using Bun's built-in server. (Architecture and Advanced Topics / Server-Side Rendering)
- fucking-awesome-angular - ngx-bun - High-performance SSR/SSG adapter for Angular 19+ using Bun's built-in server. (Architecture and Advanced Topics / Server-Side Rendering)
README
# @pegasusheavy/ngx-bun
+
High-performance SSR/SSG adapter for Angular 19+ using Bun's built-in server
---
## Features
- 🚀 **Blazing Fast** - Leverages Bun's high-performance HTTP server and runtime
- 📦 **Full SSR Support** - Complete server-side rendering for Angular 19+
- 🏗️ **SSG/Prerendering** - Generate static HTML files at build time
- 🔄 **Automatic Hydration** - Seamless client-side hydration
- 📁 **Static File Serving** - Optimized static asset serving with compression
- 💾 **Built-in Caching** - LRU cache for rendered pages
- 🛠️ **Angular CLI Integration** - Schematics for easy setup with `ng add`
- 🔧 **Custom Builders** - Angular CLI builders for development and production
## Requirements
- **Angular** 19.0.0 or higher
- **Bun** 1.0.0 or higher
- **Node.js** 20.0.0 or higher (for Angular CLI)
## Installation
### Using Angular CLI (Recommended)
```bash
ng add @pegasusheavy/ngx-bun
```
This will:
1. Install the package and dependencies
2. Generate the server file (`server.ts`)
3. Create server-side configuration files
4. Update `angular.json` with SSR targets
5. Add npm scripts for development and production
### Manual Installation
```bash
# Install the package
pnpm add @pegasusheavy/ngx-bun
# Install peer dependencies
pnpm add @angular/ssr @angular/platform-server
```
## Quick Start
### 1. Add SSR to your Angular project
```bash
ng add @pegasusheavy/ngx-bun
```
### 2. Start the development server
```bash
pnpm dev:ssr
```
### 3. Build for production
```bash
pnpm build:ssr
```
### 4. Serve production build
```bash
pnpm serve:ssr
```
## Configuration
### Server Configuration
The generated `server.ts` file can be customized:
```typescript
import { createBunServer, createBunAngularEngine } from '@pegasusheavy/ngx-bun';
const engine = createBunAngularEngine({
bootstrap: () => import('./src/main.server'),
browserDistFolder: './dist/my-app/browser',
// Cache configuration
enableCache: true,
maxCacheSize: 100,
cacheTtl: 300_000, // 5 minutes
});
createBunServer({
engine,
port: 4000,
hostname: 'localhost',
// Enable request logging
logging: true,
// Routes to skip SSR (client-only)
clientOnlyRoutes: ['/admin/*'],
// Development mode
development: process.env.NODE_ENV !== 'production',
});
```
### Route Rendering Configuration
Configure how each route is rendered in `app.routes.server.ts`:
```typescript
import { RenderMode, ServerRoute } from '@angular/ssr';
export const serverRoutes: ServerRoute[] = [
// Client-side only (no SSR)
{ path: 'admin/**', renderMode: RenderMode.Client },
// Prerendered at build time (SSG)
{ path: 'about', renderMode: RenderMode.Prerender },
{ path: 'blog/:slug', renderMode: RenderMode.Prerender },
// Server-side rendered on each request (SSR)
{ path: '**', renderMode: RenderMode.Server },
];
```
### Angular.json Targets
The schematic adds these targets to your `angular.json`:
```json
{
"serve-ssr": {
"builder": "@pegasusheavy/ngx-bun:serve",
"options": {
"browserTarget": "my-app:build",
"port": 4000
}
},
"prerender": {
"builder": "@pegasusheavy/ngx-bun:prerender",
"options": {
"browserTarget": "my-app:build:production",
"routes": ["/", "/about", "/contact"]
}
}
}
```
## API
### `createBunAngularEngine(options)`
Creates the Angular SSR engine.
```typescript
interface BunAngularEngineOptions {
// Angular bootstrap function
bootstrap: () => Promise;
// Path to browser distribution
browserDistFolder: string;
// Path to server distribution (optional)
serverDistFolder?: string;
// Custom index.html path (optional)
indexHtml?: string;
// Additional providers (optional)
providers?: Provider[];
// Enable render caching (default: true)
enableCache?: boolean;
// Max cache entries (default: 100)
maxCacheSize?: number;
// Cache TTL in ms (default: 300000)
cacheTtl?: number;
}
```
### `createBunServer(options)`
Creates and starts the Bun server.
```typescript
interface BunServerOptions {
// The Angular engine instance
engine: BunAngularEngine;
// Server port (default: 4000)
port?: number;
// Server hostname (default: 'localhost')
hostname?: string;
// Enable static file serving (default: true)
serveStatic?: boolean;
// Static files directory
staticDir?: string;
// Development mode (default: false)
development?: boolean;
// Enable request logging (default: false)
logging?: boolean;
// Routes to skip SSR
clientOnlyRoutes?: string[];
// TLS configuration for HTTPS
tls?: { cert: string; key: string };
// Server start callback
onStart?: (server: Server) => void;
}
```
### `createRequestHandler(options)`
Creates a request handler for custom server setups.
```typescript
import { createRequestHandler } from '@pegasusheavy/ngx-bun';
const handler = createRequestHandler({
engine,
staticHandler,
logging: true,
});
// Use with Bun.serve directly
Bun.serve({
fetch: handler,
port: 4000,
});
```
### `createStaticFileHandler(options)`
Creates a static file handler with caching and compression.
```typescript
interface StaticFileOptions {
// Root directory for static files
root: string;
// Index file name (default: 'index.html')
index?: string;
// Enable compression (default: true)
compression?: boolean;
// Custom MIME types
mimeTypes?: Record;
// Cache control header
cacheControl?: string | ((path: string) => string);
}
```
## Prerendering (SSG)
### Using Angular CLI
```bash
ng run my-app:prerender
```
### Programmatic API
```typescript
import { prerenderRoutes } from '@pegasusheavy/ngx-bun/prerender';
const result = await prerenderRoutes({
engineOptions: {
bootstrap,
browserDistFolder: './dist/browser',
},
routes: ['/', '/about', '/blog/post-1', '/blog/post-2'],
outputDir: './dist/prerendered',
concurrency: 5,
generateSitemap: true,
baseUrl: 'https://example.com',
onProgress: (completed, total, path) => {
console.log(`[${completed}/${total}] ${path}`);
},
});
console.log(`Prerendered ${result.success} routes in ${result.totalTime}ms`);
```
### Dynamic Route Parameters
```typescript
const result = await prerenderRoutes({
routes: [
'/',
'/about',
{
path: '/blog/:slug',
getParams: async () => {
// Fetch slugs from CMS or database
const posts = await fetchBlogPosts();
return posts.map(post => ({ slug: post.slug }));
},
},
],
// ...
});
```
## Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `NODE_ENV` | Environment mode | `development` |
| `PORT` | Server port | `4000` |
| `HOST` | Server hostname | `localhost` |
| `BROWSER_DIST_FOLDER` | Browser dist path | Auto-detected |
| `SERVER_DIST_FOLDER` | Server dist path | Auto-detected |
## Performance Tips
1. **Enable caching** in production for frequently accessed pages
2. **Use prerendering** for static content that doesn't change often
3. **Set appropriate cache headers** for static assets
4. **Use `clientOnlyRoutes`** for pages that don't benefit from SSR
5. **Monitor render times** using the `X-Render-Time` response header
## Comparison with Express-based SSR
| Feature | @pegasusheavy/ngx-bun | Express SSR |
|---------|-------------------|-------------|
| Cold Start | ~50ms | ~200ms |
| Memory Usage | Lower | Higher |
| Requests/sec | Higher | Lower |
| Bundle Size | Smaller | Larger |
| Native TypeScript | ✅ | ❌ |
## Troubleshooting
### "Could not find index.html"
Make sure you've built the browser application first:
```bash
ng build
```
### "Server bootstrap not found"
Ensure `main.server.ts` exists and exports a bootstrap function:
```typescript
// src/main.server.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { config } from './app/app.config.server';
const bootstrap = () => bootstrapApplication(AppComponent, config);
export default bootstrap;
```
### Hydration Mismatch Errors
Ensure your components handle server/browser differences:
```typescript
import { isPlatformBrowser } from '@angular/common';
import { PLATFORM_ID, inject } from '@angular/core';
@Component({...})
export class MyComponent {
private platformId = inject(PLATFORM_ID);
ngOnInit() {
if (isPlatformBrowser(this.platformId)) {
// Browser-only code
}
}
}
```
## Contributing
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details.
## License
MIT © [Pegasus Heavy Industries](https://github.com/pegasusheavy)
## Support
- 📖 [Documentation](https://github.com/pegasusheavy/ngx-bun#readme)
- 🐛 [Issue Tracker](https://github.com/pegasusheavy/ngx-bun/issues)
- 💬 [Discussions](https://github.com/pegasusheavy/ngx-bun/discussions)
---
Made with ❤️ for the Angular community