express-sharp adds real-time image processing routes to your express application. Images are processed with sharp, a fast Node.js module for resizing images.
express-sharp
Express app endpoint image path transformation βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββββββββββ
https://example.com/path/to/my-scaler/images/my-image.jpg?w=100&h=50
Original images are loaded via an image adapter. Currently this includes HTTP and file system adapters.
- Fast resizing of images (see sharp Performance)
- Supports multiple backends, from which the original images are downloaded
- Supports multiple caching backends
- Image URLs can be signed to prevent attacks
$ yarn add express-sharpSee sharp installation for additional installation instructions.
Example app.js (See also example/app.ts in this project):
importexpressfrom'express'import{expressSharp,FsAdapter,HttpAdapter}from'express-sharp'constapp=express()// Fetch original images via HTTPapp.use('/some-http-endpoint',expressSharp({imageAdapter: newHttpAdapter({prefixUrl: 'http://example.com/images',}),}))// Alternative: Load original images from diskapp.use('/fs-endpoint',expressSharp({imageAdapter: newFsAdapter(path.join(__dirname,'images')),}))app.listen(3000)Render /images/image.jpg with 400x400 pixels:
curl http://my-server/express-sharp-endpoint/images/image.jpg?w=400&h=400Same as above, but with 80% quality, webp image type and with progressive enabled:
curl http://my-server/express-sharp-endpoint/images/image.jpg?w=400&h=400&f=webp&q=80&pimport{expressSharp}from'express-sharp'app.use('/some-http-endpoint',expressSharp(options))Supported options:
| Name | Description | Default |
|---|---|---|
autoUseWebp | Specifies whether images should automatically be rendered in webp format when supported by the browser. | true |
cache | If specified, the keyv cache configured here is used to cache the retrieval of the original images and the transformations. | - |
cors | Any valid CORS configuration option | - |
imageAdapter | Configures the image adapter to be used (see below). Must be specified. | - |
secret | If specified, express-sharp will validate the incoming request to verify that a valid signature has been provided. The secret is used to compute this signature. | - |
express-sharp contains the following standard image adapters.
With this adapter original images are loaded from the hard disk.
import{FsAdapter}from'express-sharp'constadapter=newFsAdapter('/path/to/images')Loads original images via HTTP. To use this adapter, the peer dependency got must be installed:
$ yarn add gotimport{HttpAdapter}from'express-sharp'constadapter=newHttpAdapter({prefixUrl: 'http://localhost:3000/images',})The constructor can be passed any got options.
Loads images from Amazon S3. To use this adapter, the peer dependency aws-sdk must be installed:
$ yarn add aws-sdkimport{S3Adapter}from'express-sharp'constbucketName='my-bucketname'constadapter=newS3Adapter(bucketname)The AWS SDK expects the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be set.
If you needed your own adapters can be used. An "image adapter" is a class that implements the ImageAdapter interface:
import{ImageAdapter}from'express-sharp'classMyAdapterimplementsImageAdapter{asyncfetch(id: string): Promise<Buffer|undefined>{if(imageDoesNotExist(id)){returnundefined}returnBuffer.from('my image blob')}}The fetching of the original images and the transformations can be cached. To enable this feature, the cache option must be passed to the expressSharp middleware. Any keyv cache stores can be passed.
In-memory cache example:
constcache=newKeyv({namespace: 'express-sharp'})app.use('/my-endpoint',expressSharp({
cache,imageAdapter: ...
}))Redis example:
constcache=newKeyv('redis://',{namespace: 'express-sharp'}app.use('/my-endpoint',expressSharp({
cache,imageAdapter: ...
}))By setting the environment variable EXPRESS_SHARP_SIGNED_URL_SECRET or by specifying the secret option when calling the express-sharp middleware, signed URLs are activated. This reduces the attack surface on the server, since the caller cannot produce an unlimited number of URLs that cause load on the server.
In order to compute the signature, the supplied client should be used:
import{createClient}from'express-sharp'constendpoint='https://example.com/my-express-sharp-endpoint'constsecret='test'constclient=createClient(endpoint,secret)constimageUrl=client.url('/foo.png',{width: 500})// https://example.com/my-express-sharp-endpoint/foo.png?w=500&s=Of3ty8QY-NDhCsIrgIHvPvbokkDcxV8KtaYUB4NFRd8This project uses debug. To display debug messages from express-sharp, the DEBUG environment variable must be exported so that it contains the value express-sharp*. Example:
$ export DEBUG='my-app:*,express-sharp*'express-sharp comes with a client that can be used to generate URLs for images.
import{createClient}from'express-sharp'constclient=createClient('http://my-base-host','optional secret')constoriginalImageUrl='/foo.png'constoptions={width: 500}constfooUrl=client.url(originalImageUrl,options)Currently the following transformations can be applied to images:
| Client option name | Query param name | Description |
|---|---|---|
| quality | q | Quality is a number between 1 and 100 (see sharp docs). |
| width | w | |
| height | h | |
| format | f | Output image format. Valid values: every valid sharp output format string, i.e. jpeg, gif, webp or raw. |
| progressive | p | Only available for jpeg and png formats. Enable progressive scan by passing true. |
| crop | c | Setting crop to true enables the sharp cropping feature. Note: Both width and height params are neccessary for crop to work. Default is false. |
| trim | t | Setting trim to true enables the sharp trim feature. |
| gravity | g | When the crop option is activated you can specify the gravity of the cropping. Possible attributes of the optional gravity are north, northeast, east, southeast, south, southwest, west, northwest, center and centre. Default is center. |
express-sharp is distributed under the MIT license. See LICENSE for details.
