{"id":21214805,"url":"https://github.com/filestack/adaptive","last_synced_at":"2025-07-10T10:30:43.843Z","repository":{"id":26545962,"uuid":"109168042","full_name":"filestack/adaptive","owner":"filestack","description":"Generate responsive HTML picture elements powered by on-the-fly Filestack image conversions.","archived":false,"fork":false,"pushed_at":"2023-01-03T18:06:13.000Z","size":2235,"stargazers_count":31,"open_issues_count":15,"forks_count":3,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-03-25T21:52:59.547Z","etag":null,"topics":["adaptive","filestack","html5","html5-picture","image-resizing","images","jsx","picture","react","responsive","webp"],"latest_commit_sha":null,"homepage":"https://filestack.github.io/adaptive/","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/filestack.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-01T18:30:22.000Z","updated_at":"2023-09-30T04:39:36.000Z","dependencies_parsed_at":"2023-01-14T04:54:10.485Z","dependency_job_id":null,"html_url":"https://github.com/filestack/adaptive","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filestack%2Fadaptive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filestack%2Fadaptive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filestack%2Fadaptive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filestack%2Fadaptive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/filestack","download_url":"https://codeload.github.com/filestack/adaptive/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225632862,"owners_count":17499876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["adaptive","filestack","html5","html5-picture","image-resizing","images","jsx","picture","react","responsive","webp"],"created_at":"2024-11-20T21:31:06.864Z","updated_at":"2024-11-20T21:31:07.330Z","avatar_url":"https://github.com/filestack.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.filestack.com\"\u003e\u003cimg src=\"http://static.filestackapi.com/adaptive/adaptive.svg?refresh\" align=\"center\" width=\"230\" /\u003e\u003c/a\u003e  \n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Generate responsive HTML picture elements powered by  on-the-fly \u003ca href=\"https://github.com/filestack/\"\u003eFilestack\u003c/a\u003e image conversions.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://travis-ci.org/filestack/adaptive\"\u003e\n    \u003cimg src=\"https://travis-ci.org/filestack/adaptive.svg?branch=develop\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://npmjs.com/package/filestack-adaptive\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/filestack-adaptive.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://static.filestackapi.com/adaptive/1.4.0/adaptive.min.js\"\u003e\n    \u003cimg src=\"http://img.badgesize.io/http://static.filestackapi.com/adaptive/1.4.0/adaptive.min.js?compression=gzip\u0026color=green\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://static.filestackapi.com/adaptive/1.4.0/adaptive.min.js\"\u003e\n    \u003cimg src=\"http://img.badgesize.io/http://static.filestackapi.com/adaptive/1.4.0/adaptive.min.js?color=green\" /\u003e\n  \u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/module%20formats-cjs%2C%20umd%2C%20esm-green.svg\" /\u003e\n  \u003cbr/\u003e\n  \u003cimg src=\"https://badges.herokuapp.com/browsers?labels=none\u0026googlechrome=38\u0026firefox=38\u0026microsoftedge=13\u0026safari=9.1\u0026opera=25\" /\u003e\n\u003c/p\u003e\n\n\u003chr/\u003e\n\n**Table of Contents**\n\n\u003c!-- toc --\u003e\n- [What is Adaptive](#what-is-adaptive)\n  - [Features](#features)\n- [Usage](#usage)\n  - [Browser](#browser)\n    - [SRI](#sri)\n  - [Node (react example)](#node-react-example)\n    - [Use with JSX](#use-with-jsx)\n  - [Storage aliases and external urls](#storage-aliases-and-external-urls)\n  - [Image width and pixel density](#image-width-and-pixel-density)\n  - [Webcomponent](#webcomponent)\n  - [Using width descriptors](#using-width-descriptors)\n  - [WebP support](#webp-support)\n  - [Custom CNAME](#custom-cname)\n  - [Transformations support](#transformations-support)\n    - [Disable validator](#disable-validator)\n- [Development](#development)\n- [Documentation](#documentation)\n- [Contributing](#contributing)\n- [Future](#future)\n\n## What is Adaptive\nAdaptive is a tool which allow [Filestack](https://github.com/filestack/filestack-js) users to combine the power of on-the-fly image processing with the latest standard for responsive web images.\n\n\nThis library ships with a built-in virtual DOM adapter powered by hyperx, which allows you to simply call `picture(source, options, renderer)`, where renderer can be any DOM builder supported by hyperx (e.g React.createElement). If renderer is not provided then picture will default to returning plain DOM. \n\n\n### Features\n- Focus on usability and performance\n- Works with Filestack [handles](https://www.filestack.com/docs/concepts/getting-started/#vocabulary), [storage aliases](https://www.filestack.com/docs/concepts/storage/#storage-aliases) and external urls\n- Support for different sizes and formats in srcSet\n- Allows you to add some [image transformations](https://www.filestack.com/docs/api/processing/#image-transformations)\n- Easily integrable with external virtual DOM renderers\n\n## Usage\n\n### Browser\nYou can find the newest version at https://static.filestackapi.com/adaptive/1.4.0/adaptive.min.js\n\u003cbr\u003e\n```html\n    \u003cscript src=\"https://static.filestackapi.com/adaptive/1.4.0/adaptive.min.js\" crossorigin=\"anonymous\"\u003e\u003c/script\u003e\n    \u003cscript\u003e\n        const options = {\n            alt: 'windsurfer',\n            sizes: {\n                fallback: '60vw',\n            }\n        };\n        const el = fsAdaptive.picture(FILESTACK_HANDLE, options);\n        document.body.appendChild(el);\n    \u003c/script\u003e\n```\nOutput:\n```html\n\u003cpicture\u003e\n    \u003cimg src=\"https://cdn.filestackcontent.com/5aYkEQJSQCmYShsoCnZN\"\n         srcset=\"\n            https://cdn.filestackcontent.com/resize=width:180/5aYkEQJSQCmYShsoCnZN 180w, \n            https://cdn.filestackcontent.com/resize=width:360/5aYkEQJSQCmYShsoCnZN 360w, \n            https://cdn.filestackcontent.com/resize=width:540/5aYkEQJSQCmYShsoCnZN 540w, \n            https://cdn.filestackcontent.com/resize=width:720/5aYkEQJSQCmYShsoCnZN 720w, \n            https://cdn.filestackcontent.com/resize=width:900/5aYkEQJSQCmYShsoCnZN 900w, \n            https://cdn.filestackcontent.com/resize=width:1080/5aYkEQJSQCmYShsoCnZN 1080w, \n            https://cdn.filestackcontent.com/resize=width:1296/5aYkEQJSQCmYShsoCnZN 1296w, \n            https://cdn.filestackcontent.com/resize=width:1512/5aYkEQJSQCmYShsoCnZN 1512w, \n            https://cdn.filestackcontent.com/resize=width:1728/5aYkEQJSQCmYShsoCnZN 1728w, \n            https://cdn.filestackcontent.com/resize=width:1944/5aYkEQJSQCmYShsoCnZN 1944w, \n            https://cdn.filestackcontent.com/resize=width:2160/5aYkEQJSQCmYShsoCnZN 2160w, \n            https://cdn.filestackcontent.com/resize=width:2376/5aYkEQJSQCmYShsoCnZN 2376w, \n            https://cdn.filestackcontent.com/resize=width:2592/5aYkEQJSQCmYShsoCnZN 2592w,\n            https://cdn.filestackcontent.com/resize=width:2808/5aYkEQJSQCmYShsoCnZN 2808w, \n            https://cdn.filestackcontent.com/resize=width:3024/5aYkEQJSQCmYShsoCnZN 3024w\"\n         alt=\"photo_01\" \n         sizes=\"60vw\"\u003e\n\u003c/picture\u003e\n```\n#### SRI\nSubresource Integrity (SRI) is a security feature that enables browsers to verify that files they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched file must match\n\nTo obtain sri hashes for adaptive library check manifest.json file on CDN:\n\n```\nhttps://static.filestackapi.com/adaptive/{LIBRARY_VERSION}/manifest.json\n```\n\n```HTML\n\u003cscript src=\"//static.filestackapi.com/adaptive/{LIBRARY_VERSION}/adaptive.min.js\" integrity=\"{FILE_HASH}\" crossorigin=\"anonymous\"\u003e\u003c/script\u003e\n```\n\nWhere ```{LIBRARY_VERSION}``` is currently used library version and ```{FILE_HASH}``` is one of the hashes from integrity field in manifest.json file\n\n\n### Node (react example)\n```bash\nnpm install filestack-adaptive\n```\n```js\nimport react from 'react';\nimport reactDOM from 'react-dom';\nimport { picture } from 'filestack-adaptive';\n\n// Need to spread children parameter to prevent React key warnings\nconst createElement = (Component, props, children) =\u003e {\n  return React.createElement(Component, props, ...children);\n};\n\nconst options = { alt: 'windsurfer', sizes: { fallback: '100vw' } };\nconst tree = picture(FILESTACK_HANDLE, options, createElement);\nReactDOM.render(tree, document.body);\n```\n#### Use with JSX\nIn a case of need to create your own `\u003cpicture/\u003e` element you can call **makePictureTree** directly in your JSX\n```js\nimport React, { Component } from 'react';\nimport { makePictureTree } from 'filestack-adaptive';\n\nclass Picture extends Component {\n  renderSources(sources) {\n    return sources.map((sourceObj) =\u003e {\n      return \u003csource {...sourceObj} /\u003e;\n    });\n  }\n  renderImage(imageObj) {\n    return \u003cimg {...imageObj} /\u003e;\n  }\n  render() {\n    const tree = makePictureTree(this.props.handle, this.props);\n    return (\n      \u003cpicture\u003e\n        {tree.sources \u0026\u0026 this.renderSources(tree.sources)}\n        {this.renderImage(tree.img)}\n      \u003c/picture\u003e\n    );\n  }\n}\n\nexport default Picture;\n```\n### Storage aliases and external urls\nYou can also use [Filestack storage alias](https://www.filestack.com/docs/concepts/storage/#storage-aliases) or external urls as an image source:\n```html\n  \u003cscript src=\"https://static.filestackapi.com/adaptive/1.4.0/adaptive.min.js\"\u003e\u003c/script\u003e\n  \u003cscript\u003e\n      const options = {\n          alt: 'windsurfer',\n          sizes: {\n              fallback: '60vw',\n          }\n      };\n      const srcHandle1 = {\n        srcHandle: 'src://your_storage_alias_name/example.jpg',\n        apiKey: 'YOUR_FILESTACK_API_KEY'\n      };\n      const el1 = fsAdaptive.picture(srcHandle1, options);\n      document.body.appendChild(el1);\n\n\n      const srcHandle2 = {\n        srcHandle: 'https://yourdomain.com/photo1.jpg,\n        apiKey: 'YOUR_FILESTACK_API_KEY'\n      };\n      const el2 = fsAdaptive.picture(srcHandle2, options);\n      document.body.appendChild(el2);\n  \u003c/script\u003e\n```\n### Image width and pixel density\n\nWhen the image width is known it will generate a srcset for HiDPI screens at 2x. More densities can be specified \nby passing an array to the `resolutions` option, e.g. `resolutions: ['1x', '2x', '3x']`.\n\n```js\nconst options = { \n  alt: 'windsurfer', \n  width: '768px',\n};\npicture(FILESTACK_HANDLE, options);\n```\n\nOutput:\n\n```html\n\u003cpicture\u003e\n  \u003cimg src=\"https://cdn.filestackcontent.com/resize=width:768/5aYkEQJSQCmYShsoCnZN\" \n       srcset=\"https://cdn.filestackcontent.com/resize=width:768/5aYkEQJSQCmYShsoCnZN 1x, \n               https://cdn.filestackcontent.com/resize=width:1536/5aYkEQJSQCmYShsoCnZN 2x\" \n       alt=\"windsurfer\" \n       width=\"768\"\u003e\n\u003c/picture\u003e\n```\n\n### Webcomponent\nAdaptive now supports webcomponent. Supported options: src, width, alt, cname, policy, signature, keys, resolutions\n```HTML\n\u003cfs-adaptive src=\"NxW2v528S9W6K1l5LnFS\" width=\"769px\" alt=\"windsurfer\" \u003e\u003c/fs-adaptive\u003e\n```\n\nOutput:\n\n```html\n\u003cpicture\u003e\n  \u003cimg src=\"https://cdn.filestackcontent.com/resize=width:768/NxW2v528S9W6K1l5LnFS\" \n       srcset=\"https://cdn.filestackcontent.com/resize=width:768/NxW2v528S9W6K1l5LnFS 1x, \n               https://cdn.filestackcontent.com/resize=width:1536/NxW2v528S9W6K1l5LnFS 2x\" \n       alt=\"windsurfer\" \n       width=\"768\"\u003e\n\u003c/picture\u003e\n```\n\n### Using width descriptors\n\nYou can specify generated widths by using `resolutions`, which takes an array \nof numbers or strings (e.g. `540` or `'540w'`).\n\n```js\nconst options = { \n  alt: 'windsurfer', \n  sizes: {\n    '(min-width: 1080px)': '100vw',\n    fallback: '90vw',\n  },\n  resolutions: [540, 1080],\n};\npicture(FILESTACK_HANDLE, options);\n```\n\nOutput:\n\n```html\n\u003cpicture\u003e\n  \u003csource media=\"(min-width: 1080px)\" \n          sizes=\"100vw\" \n          srcset=\"https://cdn.filestackcontent.com/resize=width:540/5aYkEQJSQCmYShsoCnZN 540w, \n          https://cdn.filestackcontent.com/resize=width:1080/5aYkEQJSQCmYShsoCnZN 1080w\"\u003e \n  \u003cimg src=\"https://cdn.filestackcontent.com/5aYkEQJSQCmYShsoCnZN\" \n       srcset=\"https://cdn.filestackcontent.com/resize=width:540/5aYkEQJSQCmYShsoCnZN 540w, \n               https://cdn.filestackcontent.com/resize=width:1080/5aYkEQJSQCmYShsoCnZN 1080w\" \n       alt=\"windsurfer\" \n       sizes=\"90vw\"\u003e\n\u003c/picture\u003e\n```\n\n### WebP support\n\nWebP can be used when it's supported by the browser. Filestack will take care of the image conversion \nand cache it on the delivery network for future requests.\n\n```js\nconst options = { \n  alt: 'windsurfer', \n  formats: ['webp', 'jpg'], // order matters!\n};\npicture(FILESTACK_HANDLE, options);\n```\n\nOutput:\n\n```html\n\u003cpicture\u003e\n  \u003csource srcset=\"https://cdn.filestackcontent.com/output=format:webp/5aYkEQJSQCmYShsoCnZN\" \n          type=\"image/webp\"\u003e\n  \u003csource srcset=\"https://cdn.filestackcontent.com/output=format:jpg/5aYkEQJSQCmYShsoCnZN\" \n          type=\"image/jpg\"\u003e \n  \u003cimg src=\"https://cdn.filestackcontent.com/5aYkEQJSQCmYShsoCnZN\" alt=\"windsurfer\"\u003e\n\u003c/picture\u003e\n```\n### Custom CNAME\n\nIn order to use custom cname for generated file links just use cname option: \n```js\nconst options = { \n  cname: 'fs.test123.com'\n};\npicture(FILESTACK_HANDLE, options);\n```\n\nOutput:\n```html\n\u003cpicture\u003e\n  \u003cimg src=\"https://cdn.fs.test123.com/5aYkEQJSQCmYShsoCnZN\"\u003e\n\u003c/picture\u003e\n```\n\n### Transformations support\n\nAdaptive also supports Filestack transformations.\nAvailable options are listed in doc:\n\nhttps://www.filestack.com/docs/image-transformations\n\n```js\nconst options = {\n  alt: 'windsurfer', \n  width: 400,\n  transforms: {\n    blur: {\n      amount: 5\n    },\n    border: true, // use default options of border transformation\n  }\n};\npicture(FILESTACK_HANDLE, options);\n```\n\nOutput:\n\n```html\n\u003cpicture\u003e\n  \u003cimg src=\"https://cdn.filestackcontent.com/blur=amount:5/border/resize=width:400/5aYkEQJSQCmYShsoCnZN\" srcset=\"https://cdn.filestackcontent.com/blur=amount:5/border/resize=width:400/5aYkEQJSQCmYShsoCnZN 1x, https://cdn.filestackcontent.com/blur=amount:5/border/resize=width:800/5aYkEQJSQCmYShsoCnZN 2x\" alt=\"windsurfer\" width=\"400\"\u003e\n\u003c/picture\u003e\n\n```\n#### Disable validator\nTo speed up generating of final output (useful when you have a bunch of images on your site) you can optionally disable validation of transformation params by passing additional prop in options:\n```js\nconst options = {\n  ...\n  useValidator: false,\n  ...\n}\n```\n\n## Development\nTo install and work on Adaptiv locally:\n```bash\ngit clone git@github.com:filestack/adaptive.git\ncd adaptive\nnpm install\n```\nTo create build directory:\n```\nnpm run build\n```\nThis newly created directory contains\n```text\nbuild/\n├── browser/                # for the UMD module (usable in HTML script tags)\n   └── index.umd.js         #\n├── main/                   # for the CommonJS module\n   ├── ...                  #\n   └── index.js             # \n└── module/                 # for the ES Module (suitable for bundlers like Webpack and Rollup)\n   ├── ...                  #\n   └── index.js             #\n```\n\n## Documentation\nFor more info about available methods and options check browser documentation:\n\u003cbr\u003e\nhttps://filestack.github.io/adaptive/\n\n## Contributing\nWe follow the [conventional commits](https://conventionalcommits.org/) specification to ensure consistent commit messages and changelog formatting.\n\n## Future\nAdaptive is joining an ecosystem already populated with many utilities for responsive images.\nWe want to remain flexible while still having some opinions on how to implement picture elements using Filestack conversions, and we know it is hard to \ncover every use case. Contributions and ideas are welcome that would help improve the usefulness of this library.\n\nCurrent ideas:\n\n* LQIP using the Filestack blur transformation\n* Compress HiDPI images using Filestack compress task\n* Implement art direction with Filestack crop \n* Develop a PostHTML transform for post-processing HTML using `makePictureTree`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilestack%2Fadaptive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffilestack%2Fadaptive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilestack%2Fadaptive/lists"}