{"id":3936,"url":"https://github.com/mrousavy/react-native-blurhash","last_synced_at":"2025-05-14T09:08:22.375Z","repository":{"id":37698443,"uuid":"270601926","full_name":"mrousavy/react-native-blurhash","owner":"mrousavy","description":"🖼️ A library to show colorful blurry placeholders while your content loads.","archived":false,"fork":false,"pushed_at":"2024-09-09T10:59:01.000Z","size":5391,"stargazers_count":1949,"open_issues_count":34,"forks_count":71,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-10-29T11:06:14.498Z","etag":null,"topics":["algorithm","blurhash","component","encoder","hacktoberfest","image","javascript","kotlin","library","loading","native-module","node","npm","placeholder","react","react-native","swift","typescript","ui","ux"],"latest_commit_sha":null,"homepage":"https://blurha.sh","language":"Kotlin","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/mrousavy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","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},"funding":{"github":"mrousavy","ko_fi":"mrousavy","custom":["https://paypal.me/mrousavy"]}},"created_at":"2020-06-08T09:08:36.000Z","updated_at":"2024-10-29T06:44:52.000Z","dependencies_parsed_at":"2024-06-18T14:43:01.966Z","dependency_job_id":"08dd919a-4d75-4e8b-aaa0-e13802a395fd","html_url":"https://github.com/mrousavy/react-native-blurhash","commit_stats":{"total_commits":304,"total_committers":15,"mean_commits":"20.266666666666666","dds":0.3223684210526315,"last_synced_commit":"39fa56e75f9dad74cc0f61b866d5848992f61219"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrousavy%2Freact-native-blurhash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrousavy%2Freact-native-blurhash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrousavy%2Freact-native-blurhash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrousavy%2Freact-native-blurhash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrousavy","download_url":"https://codeload.github.com/mrousavy/react-native-blurhash/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247953862,"owners_count":21024102,"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":["algorithm","blurhash","component","encoder","hacktoberfest","image","javascript","kotlin","library","loading","native-module","node","npm","placeholder","react","react-native","swift","typescript","ui","ux"],"created_at":"2024-01-05T20:16:55.838Z","updated_at":"2025-04-09T01:23:00.761Z","avatar_url":"https://github.com/mrousavy.png","language":"Kotlin","readme":"\u003ca href=\"https://margelo.io\"\u003e\n  \u003cimg src=\"./img/banner.svg\" width=\"100%\" /\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://github.com/sponsors/mrousavy\"\u003e\n  \u003cimg align=\"right\" width=\"160\" alt=\"This library helped you? Consider sponsoring!\" src=\".github/funding-octocat.svg\"\u003e\n\u003c/a\u003e\n\n# Blurhash\n\n\u003e 🖼️ Give your users the loading experience they want.\n\nInstall via [npm](https://www.npmjs.com/package/react-native-blurhash):\n\n```sh\nnpm i react-native-blurhash\nnpx pod-install\n```\n\n[![npm](https://img.shields.io/npm/v/react-native-blurhash?color=%238B83E6)](https://www.npmjs.com/package/react-native-blurhash)\n[![npm](https://img.shields.io/npm/dt/react-native-blurhash?color=%238B83E6)](https://www.npmjs.com/package/react-native-blurhash)\n\n[![GitHub followers](https://img.shields.io/github/followers/mrousavy?label=Follow%20%40mrousavy\u0026style=social)](https://github.com/mrousavy?tab=followers)\n[![Twitter Follow](https://img.shields.io/twitter/follow/mrousavy?label=Follow%20%40mrousavy\u0026style=social)](https://twitter.com/mrousavy)\n\n**BlurHash** is a compact representation of a placeholder for an image. Instead of displaying boring grey little boxes while your image loads, show a _blurred preview_ until the full image has been loaded.\n\n\u003e The algorithm was created by [woltapp/blurhash](https://github.com/woltapp/blurhash), which also includes an [algorithm explanation](https://github.com/woltapp/blurhash/blob/master/Algorithm.md).\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp align=\"center\"\u003e\n    \u003cimg align=\"center\" src=\"https://github.com/mrousavy/react-native-blurhash/raw/master/img/explanation.png\" alt=\"Turn grey image boxes into colorful blurred images\" width=\"70%\"\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n## Expo\n\n- ✅ You can use this library with [Development Builds](https://docs.expo.dev/development/introduction/). No config plugin is required.\n- ❌ This library can't be used in the \"Expo Go\" app because it [requires custom native code](https://docs.expo.dev/workflow/customizing/).\n\n## Example Workflow\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"55%\"\u003e\n\u003col\u003e\n  In order to use the Blurhash component, you have to already have a Blurhash string. See the \u003ca href=\"https://blurha.sh\"\u003eblurha.sh\u003c/a\u003e page to create example strings.\n\n  This is how I use it in my project:\n\n  \u003cli\u003eA user creates a post by calling a function on my server which expects a payload of an image and some post data (title, description, ...)\u003c/li\u003e\n  \u003cli\u003eThe function on my server then\u003c/li\u003e\n  \u003col\u003e\n    \u003cli\u003egenerates a blurhash from the image in the payload using the \u003ca href=\"https://github.com/woltapp/blurhash/tree/master/C\"\u003eC encoder\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003estores the post data (including the generated blurhash string) in my database\u003c/li\u003e\n    \u003cli\u003euploads the image to a content delivery network (e.g. AWS)\u003c/li\u003e\n  \u003c/ol\u003e\n  \u003cli\u003eNow everytime a user loads a feed of posts from my database, I can immediately show a \u003ccode\u003e\u0026lt;Blurhash\u0026gt;\u003c/code\u003e component (with the post's \u003ccode\u003e.blurhash\u003c/code\u003e property) over my \u003ccode\u003e\u0026lt;Image\u0026gt;\u003c/code\u003e component, and fade it out once the \u003ccode\u003e\u0026lt;Image\u0026gt;\u003c/code\u003e component's \u003ca href=\"https://reactnative.dev/docs/image#onloadend\"\u003e\u003ccode\u003eonLoadEnd\u003c/code\u003e\u003c/a\u003e function has been called.\u003c/li\u003e\n\n  \u003cbr/\u003e\n  \u003cblockquote\u003e\n  Note: You can also use the \u003ca href=\"#encoding\"\u003ereact-native-blurhash encoder\u003c/a\u003e to encode straight from your React Native App!\n  \u003c/blockquote\u003e\n\u003c/td\u003e\n\u003ctd width=\"25%\"\u003e\n\u003cimg src=\"https://github.com/mrousavy/react-native-blurhash/raw/master/img/demo.gif\"\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## Usage\n\nThe `\u003cBlurhash\u003e` component has the following properties:\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eName\u003c/th\u003e\n    \u003cth\u003eType\u003c/th\u003e\n    \u003cth\u003eExplanation\u003c/th\u003e\n    \u003cth\u003eRequired\u003c/th\u003e\n    \u003cth\u003eDefault Value\u003c/th\u003e\n  \u003c/td\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eblurhash\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003estring\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eThe blurhash string to use. Example: \u003ccode\u003eLGFFaXYk^6#M@-5c,1J5@[or[Q6.\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e✅\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003eundefined\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003edecodeWidth\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003enumber\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eThe width (resolution) to decode to. Higher values decrease performance, use \u003ccode\u003e16\u003c/code\u003e for large lists, otherwise you can increase it to \u003ccode\u003e32\u003c/code\u003e.\n    \u003cbr/\u003e\n    \u003cblockquote\u003eSee: \u003ca href=\"#performance\"\u003eperformance\u003c/a\u003e\u003c/blockquote\u003e\u003c/td\u003e\n    \u003ctd\u003e❌\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003e32\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003edecodeHeight\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003enumber\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eThe height (resolution) to decode to. Higher values decrease performance, use \u003ccode\u003e16\u003c/code\u003e for large lists, otherwise you can increase it to \u003ccode\u003e32\u003c/code\u003e.\n    \u003cbr/\u003e\n    \u003cblockquote\u003eSee: \u003ca href=\"#performance\"\u003eperformance\u003c/a\u003e\u003c/blockquote\u003e\u003c/td\u003e\n    \u003ctd\u003e❌\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003e32\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003edecodePunch\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003enumber\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eAdjusts the contrast of the output image. Tweak it if you want a different look for your placeholders.\u003c/td\u003e\n    \u003ctd\u003e❌\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003e1.0\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003edecodeAsync\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eAsynchronously decode the Blurhash on a background Thread instead of the UI-Thread.\n    \u003cbr/\u003e\n    \u003cblockquote\u003eSee: \u003ca href=\"#asynchronous-decoding\"\u003eAsynchronous Decoding\u003c/a\u003e\u003c/blockquote\u003e\u003c/td\u003e\n    \u003ctd\u003e❌\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eresizeMode\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003e'cover' | 'contain' | 'stretch' | 'center'\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eSets the resize mode of the image. (no, \u003ccode\u003e'repeat'\u003c/code\u003e is not supported.)\n    \u003cblockquote\u003eSee: \u003ca href=\"https://reactnative.dev/docs/image#resizemode\"\u003eImage::resizeMode\u003c/a\u003e\u003c/blockquote\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e❌\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003e'cover'\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eonLoadStart\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003e() =\u003e void\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eA callback to call when the Blurhash started to decode the given \u003ccode\u003eblurhash\u003c/code\u003e string.\u003c/td\u003e\n    \u003ctd\u003e❌\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003eundefined\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eonLoadEnd\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003e() =\u003e void\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eA callback to call when the Blurhash successfully decoded the given \u003ccode\u003eblurhash\u003c/code\u003e string and rendered the image to the \u003ccode\u003e\u0026lt;Blurhash\u0026gt;\u003c/code\u003e view.\u003c/td\u003e\n    \u003ctd\u003e❌\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003eundefined\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eonLoadError\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003e(message?: string) =\u003e void\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eA callback to call when the Blurhash failed to load. Use the \u003ccode\u003emessage\u003c/code\u003e parameter to get the error message.\u003c/td\u003e\n    \u003ctd\u003e❌\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003eundefined\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eAll \u003ccode\u003eView\u003c/code\u003e props\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003eViewProps\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eAll properties from the React Native \u003ccode\u003eView\u003c/code\u003e. Use \u003ccode\u003estyle.width\u003c/code\u003e and \u003ccode\u003estyle.height\u003c/code\u003e for display-sizes. Also, \u003ccode\u003estyle.borderRadius\u003c/code\u003e is natively supported on iOS.\u003c/td\u003e\n    \u003ctd\u003e❌\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003e{}\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\nExample Usage:\n\n```tsx\nimport { Blurhash } from 'react-native-blurhash';\n\nexport default function App() {\n  return (\n    \u003cBlurhash\n      blurhash=\"LGFFaXYk^6#M@-5c,1J5@[or[Q6.\"\n      style={{flex: 1}}\n    /\u003e\n  );\n}\n```\n\n\u003e See the [example](example/) App for a full code example.\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eiOS Screenshot\u003c/th\u003e\n    \u003cth\u003eAndroid Screenshot\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"50%\"\u003e\u003cimg src=\"https://github.com/mrousavy/react-native-blurhash/raw/master/img/demo_ios.png\" alt=\"iOS Demo Screenshot\"\u003e\u003c/td\u003e\n    \u003ctd width=\"50%\"\u003e\u003cimg src=\"https://github.com/mrousavy/react-native-blurhash/raw/master/img/demo_android.png\" alt=\"Android Demo Screenshot\"\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### Average Color\n\nIf your app is **really colorful** you might want to match some containers' colors to the content's context. To achieve this, use the `getAverageColor` function to get an RGB value which represents the average color of the given Blurhash:\n\n```ts\nconst averageColor = Blurhash.getAverageColor('LGFFaXYk^6#M@-5c,1J5@[or[Q6.')\n```\n\n### Encoding\n\nThis library also includes a **native Image encoder**, so you can **encode** Images to blurhashes straight out of your React Native App!\n\n```ts\nconst blurhash = await Blurhash.encode('https://blurha.sh/assets/images/img2.jpg', 4, 3)\n```\n\nBecause encoding an Image is a pretty heavy task, this function is **non-blocking** and runs on a separate background Thread.\n\n### Validation\n\nIf you need to validate a blurhash string, you can use `isValidBlurhash`.\n\n```ts\nconst result = Blurhash.isValidBlurhash('LGFFaXYk^6#M@-5c,1J5@[or[Q6.')\nif (result.isValid) {\n  console.log(`Blurhash is valid!`)\n} else {\n  console.log(`Blurhash is invalid! ${result.reason}`)\n}\n```\n\n## Performance\n\nThe performance of the decoders is really fast, which means you should be able to use them in collections quite easily. By increasing the `decodeWidth` and `decodeHeight` props, the _time to decode_ also increases. I'd recommend values of `16` for large lists, and `32` otherwise. Play around with the values but keep in mind that you probably won't see a difference when increasing it to anything above `32`.\n\n### Asynchronous Decoding\n\nUse `decodeAsync={true}` to decode the Blurhash on a separate background Thread instead of the main UI-Thread. This is useful when you are experiencing stutters because of the Blurhash's **decoder** - e.g.: in large Lists.\n\nThreads are re-used (iOS: `DispatchQueue`, Android: kotlinx Coroutines).\n\n### Caching\n\n#### Image\n\nA `\u003cBlurhash\u003e` component caches the rendered Blurhash (Image) as long as the `blurhash`, `decodeWidth`, `decodeHeight` and `decodePunch` properties stay the same. Because unmounting the `\u003cBlurhash\u003e` component clears the cache, re-mounting it will cause it to decode again.\n\n#### Cosine Operations\n\nCosine operations get cached in memory to avoid expensive re-calculation (~24.576 `cos(...)` calls per 32x32 blurhash). Since this can affect memory usage, you can manually clear the cosine array cache by calling:\n\n```ts\nBlurhash.clearCosineCache()\n```\n\n\u003e Note: At the moment, cosine operations are only cached on Android. Calling `clearCosineCache()` is a no-op on other platforms.\n\n## Resources\n* [this medium article.](https://teabreak.e-spres-oh.com/swift-in-react-native-the-ultimate-guide-part-2-ui-components-907767123d9e) jesus christ amen thanks for that\n* [Native Modules documentation](https://reactnative.dev/docs/native-modules-ios.html), especially the [Swift part](https://reactnative.dev/docs/native-modules-ios.html#exporting-swift)\n* [This cheatsheet gist](https://gist.github.com/chourobin/f83f3b3a6fd2053fad29fff69524f91c) thank you [**@chourobin**](https://github.com/chourobin).\n* [DylanVann/react-native-fast-image](https://github.com/DylanVann/react-native-fast-image) as a reference for native UI modules\n* [woltapp/blurhash](https://github.com/woltapp/blurhash) of course\n\n\n\u003ca href='https://ko-fi.com/F1F8CLXG' target='_blank'\u003e\u003cimg height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi2.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /\u003e\u003c/a\u003e\n","funding_links":["https://github.com/sponsors/mrousavy","https://ko-fi.com/mrousavy","https://paypal.me/mrousavy","https://ko-fi.com/F1F8CLXG'"],"categories":["Components","By Language","Kotlin"],"sub_categories":["UI","Kotlin"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrousavy%2Freact-native-blurhash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrousavy%2Freact-native-blurhash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrousavy%2Freact-native-blurhash/lists"}