{"id":48708403,"url":"https://github.com/Hasan-Kakeh/ng-image-optimizer","last_synced_at":"2026-04-13T11:01:16.063Z","repository":{"id":349342698,"uuid":"1201266408","full_name":"Hasan-Kakeh/ng-image-optimizer","owner":"Hasan-Kakeh","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-12T13:33:09.000Z","size":1553,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-12T14:14:40.543Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Hasan-Kakeh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-04T12:48:30.000Z","updated_at":"2026-04-12T13:33:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Hasan-Kakeh/ng-image-optimizer","commit_stats":null,"previous_names":["hasan-kakeh/ng-image-optimizer"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Hasan-Kakeh/ng-image-optimizer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hasan-Kakeh%2Fng-image-optimizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hasan-Kakeh%2Fng-image-optimizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hasan-Kakeh%2Fng-image-optimizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hasan-Kakeh%2Fng-image-optimizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Hasan-Kakeh","download_url":"https://codeload.github.com/Hasan-Kakeh/ng-image-optimizer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hasan-Kakeh%2Fng-image-optimizer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31749763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T09:16:15.125Z","status":"ssl_error","status_checked_at":"2026-04-13T09:16:05.023Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-11T13:00:21.208Z","updated_at":"2026-04-13T11:01:16.056Z","avatar_url":"https://github.com/Hasan-Kakeh.png","language":"TypeScript","readme":"# 🖼️ NgImageOptimizer\n\n**NgImageOptimizer** is a high-performance image optimization library for Angular SSR applications. It bridges the gap between Angular's `NgOptimizedImage` and server-side processing using [sharp](https://sharp.pixelplumbing.com/), providing a Next.js-like image optimization experience.\n\n[**Documentation**](https://hasan-kakeh.github.io/ng-image-optimizer/)\n\n---\n\n### Prerequisites\n\n- Node.js (v18+)\n- Angular CLI\n- Angular SSR\n\n---\n\n## 🚦 Quick Start\n\nThe fastest way to get started is using our automated schematic:\n\n```bash\nng add ng-image-optimizer\n```\n\n---\n\nThis command will:\n\n1. Install necessary dependencies (`sharp`).\n2. Register the image loader in your `app.config.ts`.\n3. Configure the optimization middleware in your Express `server.ts`.\n\n---\n\n### 🛠️ Manual Setup\n\nIf you prefer to configure things manually, follow these steps:\n\nInstall the library and its peer dependencies:\n\n```bash\nnpm install ng-image-optimizer sharp\n```\n\n#### Client-Side Configuration\n\nRegister the image loader in your `app.config.ts`:\n\n```typescript\nimport { provideImageOptimizerLoader } from 'ng-image-optimizer';\n\nexport const appConfig: ApplicationConfig = {\n  providers: [provideImageOptimizerLoader()],\n};\n```\n\n#### Server-Side Configuration\n\nAdd the middleware to your `server.ts` before other routes:\n\n```typescript\nimport { imageOptimizerHandler } from 'ng-image-optimizer/server';\n\n// ... early in your express app setup\nconst browserDistFolder = resolve(serverDistFolder, '../browser');\n\nserver.get('/_ng/image', imageOptimizerHandler(browserDistFolder));\n```\n\n---\n\n## ✨ Features\n\n- **🚀 Performance**: Automatic resizing, format conversion (WebP/AVIF), and quality adjustment.\n- **⚡ Seamless Integration**: Works directly with Angular's built-in `NgOptimizedImage` directive.\n- **💾 Advanced Caching**: Persistent file-based caching with LRU (Least Recently Used) logic to minimize server load.\n- **🛡️ Secure by Default**: Built-in Content Security Policy (CSP) headers and SVG protection.\n- **🛠️ Automated Setup**: Includes an `ng add` schematic for zero-config integration.\n- **🌍 Remote Image Support**: Securely fetch and optimize images from external domains via allowlists.\n\n## 🏗️ Architecture\n\nNgImageOptimizer consists of two main parts:\n\n### 1. Client-Side Loader\n\nA custom `IMAGE_LOADER` that transforms Angular's image requests into optimization queries (e.g., `/_ng/image?url=...\u0026w=1080\u0026q=75`).\n\n### 2. Server-Side Middleware\n\nAn Express middleware that intercept requests, fetches the source image (local or remote), optimizes it using `sharp`, and caches the result for future hits.\n\n```mermaid\nsequenceDiagram\n    participant Browser\n    participant Express as Server (Express)\n    participant Sharp as Optimizer (Sharp)\n    participant Disk as Cache (File System)\n\n    Browser-\u003e\u003eExpress: GET /_ng/image?url=me.jpg\u0026w=640\n    Express-\u003e\u003eDisk: Check Cache (Hash)\n    alt Cache Hit\n        Disk--\u003e\u003eExpress: Return Cached Buffer\n        Express--\u003e\u003eBrowser: 200 OK (X-Cache: HIT)\n    else Cache Miss\n        Express-\u003e\u003eExpress: Fetch Original Image\n        Express-\u003e\u003eSharp: Resize \u0026 Compress\n        Sharp--\u003e\u003eExpress: Optimized Buffer\n        Express-\u003e\u003eDisk: Save to Cache\n        Express--\u003e\u003eBrowser: 200 OK (X-Cache: MISS)\n    end\n```\n\n---\n\n## 🛞 Usage\n\nUse standard Angular `NgOptimizedImage` in your templates. The library will automatically handle the resolution and optimization.\n\n```html\n\u003cimg ngSrc=\"/photo.jpg\" width=\"800\" height=\"600\" priority /\u003e\n```\n\n---\n\n## ⚙️ Configuration\n\n### Client Provider (`ImageOptimizerLoaderOptions`)\n\nWhen registering `provideImageOptimizerLoader`, you can pass the following options:\n\n| Property         | Type     | Default      | Description                                                       |\n| :--------------- | :------- | :----------- | :---------------------------------------------------------------- |\n| `routePrefix`    | `string` | `/_ng/image` | The path where the image optimizer middleware is mounted.         |\n| `defaultWidth`   | `number` | `1080`       | The default width used if `NgOptimizedImage` doesn't provide one. |\n| `defaultQuality` | `number` | `90`         | The default image quality (1-100).                                |\n\n### Server Middleware (`ImageConfig`)\n\nWhen initializing `imageOptimizerHandler`, you can pass an optional configuration object:\n\n| Property                 | Type                     | Default                | Description                                  |\n| :----------------------- | :----------------------- | :--------------------- | :------------------------------------------- |\n| `deviceSizes`            | `number[]`               | `[640, 750, 828, ...]` | Allowed widths for device breakpoints.       |\n| `imageSizes`             | `number[]`               | `[16, 32, 48, ...]`    | Allowed widths for smaller UI elements.      |\n| `remotePatterns`         | `RemotePattern[]`        | `[]`                   | List of allowed external domains.            |\n| `localPatterns`          | `LocalPattern[]`         | `[]`                   | List of allowed local path patterns.         |\n| `minimumCacheTTL`        | `number`                 | `14400` (4h)           | Minimum time (seconds) to cache an image.    |\n| `formats`                | `string[]`               | `['image/webp']`       | Favored output formats (supports webp/avif). |\n| `dangerouslyAllowSVG`    | `boolean`                | `false`                | Whether to allow processing SVG images.      |\n| `contentSecurityPolicy`  | `string`                 | `...`                  | CSP headers for the served images.           |\n| `contentDispositionType` | `'inline'\\|'attachment'` | `'inline'`             | How the browser should handle the image.     |\n| `maxCacheSize`           | `number`                 | `52428800` (50MB)      | Maximum size of the internal LRU cache.      |\n\n---\n\n## 📄 License\n\nng-image-optimizer is an open source package released under the MIT license. See the LICENSE file for more information.\n","funding_links":[],"categories":["Third Party Components"],"sub_categories":["Images"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHasan-Kakeh%2Fng-image-optimizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHasan-Kakeh%2Fng-image-optimizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHasan-Kakeh%2Fng-image-optimizer/lists"}