{"id":13416534,"url":"https://github.com/jaredpalmer/the-platform","last_synced_at":"2025-11-01T05:03:01.917Z","repository":{"id":40003337,"uuid":"144912647","full_name":"jaredpalmer/the-platform","owner":"jaredpalmer","description":"Web. Components. 😂","archived":false,"fork":false,"pushed_at":"2022-12-09T09:39:17.000Z","size":1832,"stargazers_count":4398,"open_issues_count":39,"forks_count":106,"subscribers_count":47,"default_branch":"master","last_synced_at":"2025-04-24T05:09:22.845Z","etag":null,"topics":["hooks","react","react-hooks","react-suspense","suspense"],"latest_commit_sha":null,"homepage":"","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/jaredpalmer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["jaredpalmer"]}},"created_at":"2018-08-15T23:22:09.000Z","updated_at":"2025-04-20T10:35:08.000Z","dependencies_parsed_at":"2023-01-25T20:46:38.076Z","dependency_job_id":null,"html_url":"https://github.com/jaredpalmer/the-platform","commit_stats":null,"previous_names":["palmerhq/react-async-elements","palmerhq/the-platform"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredpalmer%2Fthe-platform","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredpalmer%2Fthe-platform/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredpalmer%2Fthe-platform/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredpalmer%2Fthe-platform/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaredpalmer","download_url":"https://codeload.github.com/jaredpalmer/the-platform/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254209859,"owners_count":22032897,"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":["hooks","react","react-hooks","react-suspense","suspense"],"created_at":"2024-07-30T21:01:00.343Z","updated_at":"2025-11-01T05:02:56.879Z","avatar_url":"https://github.com/jaredpalmer.png","language":"TypeScript","funding_links":["https://github.com/sponsors/jaredpalmer"],"categories":["TypeScript","📦 Legacy \u0026 Inactive Projects"],"sub_categories":[],"readme":"![Repo Banner](./.github/repo-banner.png)\n\n# The Platform\n\n[![Blazing Fast](https://badgen.now.sh/badge/speed/blazing%20%F0%9F%94%A5/green)](https://npm.im/the-platform) [![Discord](https://img.shields.io/discord/769256827007139912?label=%F0%9F%92%AC%20%20join%20us%20on%20discord\u0026style=plastic)](https://discord.com/invite/RevdZTYMzr)\n[![Discord](https://img.shields.io/discord/769256827007139912?label=%F0%9F%92%AC%20%20join%20us%20on%20discord\u0026style=plastic)](https://discord.com/invite/RevdZTYMzr)\n\nWeb API's turned into React Hooks and Suspense-friendly React components. #useThePlatform\n\n## Install\n\n\u003e Note: React 16.8+ is required for Hooks.\n\n### With npm\n\n```sh\nnpm i the-platform --save\n```\n\n### Or with yarn\n\n```sh\nyarn add the-platform\n```\n\n## Examples\n\n- [Basics](https://codesandbox.io/s/8kw6mpp3k9)\n- [Low Quality Image Placeholder](https://codesandbox.io/s/vo3zjoq90)\n- [Using `\u003cScript\u003e` and Stripe Checkout](https://codesandbox.io/s/wy63pynp55)\n\n## API\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Hooks](#hooks)\n  - [`useDeviceMotion()`](#usedevicemotion)\n  - [`useDeviceOrientation()`](#usedeviceorientation)\n  - [`useGeoPosition()`](#usegeoposition)\n  - [`useNetworkStatus()`](#usenetworkstatus)\n  - [`useMedia()`](#usemedia)\n  - [`useScript()`](#usescript)\n  - [`useStylesheet()`](#usestylesheet)\n  - [`useWindowScrollPosition()`](#usewindowscrollposition)\n  - [`useWindowSize()`](#usewindowsize)\n- [Components](#components)\n  - [`\u003cImg\u003e`](#img)\n  - [`\u003cScript\u003e`](#script)\n  - [`\u003cVideo\u003e`](#video)\n  - [`\u003cAudio\u003e`](#audio)\n  - [`\u003cPreload\u003e`](#preload)\n  - [`\u003cStylesheet\u003e`](#stylesheet)\n- [Authors](#authors)\n- [Inspiration](#inspiration)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Hooks\n\n### `useDeviceMotion()`\n\nDetect and retrieve current device Motion.\n\n#### Returns\n\n[`DeviceMotionEvent`](https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent)\n\n#### Example\n\n```js\nimport { useDeviceMotion } from 'the-platform';\n\nconst Example = () =\u003e {\n  const { acceleration, rotationRate, interval } = useDeviceMotion();\n\n  // ...\n};\n```\n\n### `useDeviceOrientation()`\n\nDetect and retrieve current device orientation.\n\n#### Returns\n\n[`DeviceOrientationEvent`](https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent)\n\n#### Example\n\n```js\nimport { useDeviceOrientation } from 'the-platform';\n\nconst Example = () =\u003e {\n  const { alpha, beta, gamma, absolute } = useDeviceOrientation();\n\n  // ...\n};\n```\n\n### `useGeoPosition()`\n\nRetrieve Geo position from the browser. This will throw a promise (must use with Suspense).\n\n#### Arguments\n\n[`PositionOptions`](https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions)\n\n#### Returns\n\n[`Position`](https://developer.mozilla.org/en-US/docs/Web/API/Position)\n\n#### Example\n\n```js\nimport { useGeoPosition } from 'the-platform';\n\nconst Example = () =\u003e {\n  const {\n    coords: { latitude, longitude },\n  } = useGeoPosition();\n\n  // ...\n};\n```\n\n### `useNetworkStatus()`\n\nRetrieve network status from the browser.\n\n#### Returns\n\nObject containing:\n\n- `isOnline: boolean`: `true` if the browser has network access. `false`\n  otherwise.\n\n- `offlineAt?: Date`: Date when network connection was lost.\n\n#### Example\n\n```js\nimport { useNetworkStatus } from 'the-platform';\n\nconst Example = () =\u003e {\n  const { isOnline, offlineAt } = useNetworkStatus();\n\n  // ...\n};\n```\n\n### `useMedia()`\n\n#### Arguments\n\n`query: string | object`: media query string or object (parsed by [json2mq](https://github.com/akiran/json2mq)).\n`defaultMatches: boolean`: a boolean providing a default value for matches\n\n#### Returns\n\n`match: boolean`: `true` if the media query matches, `false` otherwise.\n\n#### Example\n\n```js\nimport { useMedia } from 'the-platform';\n\nconst Example = () =\u003e {\n  const small = useMedia('(min-width: 400px)');\n  const medium = useMedia({ minWidth: 800 });\n\n  // ...\n};\n```\n\n### `useScript()`\n\nThis will throw a promise (must use with Suspense).\n\n#### Arguments\n\nObject containing:\n\n- `src: string`: The script's URI.\n\n```js\nimport { useScript } from 'the-platform';\n\nconst Example = () =\u003e {\n  const _unused = useScript({ src: 'bundle.js' });\n\n  // ...\n};\n```\n\n### `useStylesheet()`\n\nThis will throw a promise (must use with Suspense).\n\n#### Arguments\n\nObject containing:\n\n- `href: string`: The stylesheet's URI.\n- `media?: string`: Intended destination media for style information.\n\n```js\nimport { useStylesheet } from 'the-platform';\n\nconst Example = () =\u003e {\n  const _unused = useStylesheet({ href: 'normalize.css' });\n\n  // ...\n};\n```\n\n### `useWindowScrollPosition()`\n\n#### Returns\n\nObject containing:\n\n- `x: number`: Horizontal scroll in pixels (`window.pageXOffset`).\n- `y: number`: Vertical scroll in pixels (`window.pageYOffset`).\n\n#### Example\n\n```js\nimport { useWindowScrollPosition } from 'the-platform';\n\nconst Example = () =\u003e {\n  const { x, y } = useWindowScrollPosition();\n\n  // ...\n};\n```\n\n### `useWindowSize()`\n\n#### Returns\n\nObject containing:\n\n- `width`: Width of browser viewport (`window.innerWidth`)\n- `height`: Height of browser viewport (`window.innerHeight`)\n\n#### Example\n\n```js\nimport { useWindowSize } from 'the-platform';\n\nconst Example = () =\u003e {\n  const { width, height } = useWindowSize();\n\n  // ...\n};\n```\n\n## Components\n\n### `\u003cImg\u003e`\n\n#### Props\n\n- `src: string`\n- anything else you can pass to an `\u003cimg\u003e` tag\n\n```js\nimport React from 'react';\nimport { Img } from 'the-platform';\n\nfunction App() {\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eHello\u003c/h1\u003e\n      \u003cReact.Suspense maxDuration={300} fallback={'loading...'}\u003e\n        \u003cImg src=\"https://source.unsplash.com/random/4000x2000\" /\u003e\n      \u003c/React.Suspense\u003e\n    \u003c/div\u003e\n  );\n}\n\nexport default App;\n```\n\n### `\u003cScript\u003e`\n\n#### Props\n\n- `src: string`\n- `children?: () =\u003e React.ReactNode` - This render prop will only execute _after_ the script has loaded.\n- anything else you can pass to a `\u003cscript\u003e` tag\n\n```js\nimport React from 'react';\nimport { Script } from 'the-platform';\n\nfunction App() {\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eLoad Stripe.js Async\u003c/h1\u003e\n      \u003cReact.Suspense maxDuration={300} fallback={'loading...'}\u003e\n        \u003cScript src=\"https://js.stripe.com/v3/\" async\u003e\n          {() =\u003e console.log(window.Stripe) || null}\n        \u003c/Script\u003e\n      \u003c/React.Suspense\u003e\n    \u003c/div\u003e\n  );\n}\n\nexport default App;\n```\n\n### `\u003cVideo\u003e`\n\n#### Props\n\n- `src: string`\n- anything else you can pass to a `\u003cvideo\u003e` tag\n\n```js\nimport React from 'react';\nimport { Video } from 'the-platform';\n\nfunction App() {\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eKen Wheeler on a Scooter\u003c/h1\u003e\n      \u003cReact.Suspense maxDuration={300} fallback={'loading...'}\u003e\n        \u003cVideo\n          src=\"https://video.twimg.com/ext_tw_video/1029780437437014016/pu/vid/360x640/QLNTqYaYtkx9AbeH.mp4?tag=5\"\n          preload=\"auto\"\n          autoPlay\n        /\u003e\n      \u003c/React.Suspense\u003e\n    \u003c/div\u003e\n  );\n}\n\nexport default App;\n```\n\n### `\u003cAudio\u003e`\n\n#### Props\n\n- `src: string`\n- anything else you can pass to a `\u003caudio\u003e` tag\n\n```js\nimport React from 'react';\nimport { Audio } from 'the-platform';\n\nfunction App() {\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eMeavy Boy - Compassion\u003c/h1\u003e\n      {/* source: http://freemusicarchive.org/music/Meavy_Boy/EP_71_to_20/Compassion */}\n      \u003cReact.Suspense maxDuration={300} fallback={'loading...'}\u003e\n        \u003cAudio src=\"https://file-dnzavydoqu.now.sh/\" preload=\"auto\" autoPlay /\u003e\n      \u003c/React.Suspense\u003e\n    \u003c/div\u003e\n  );\n}\n\nexport default App;\n```\n\n### `\u003cPreload\u003e`\n\nPreload a resource with `\u003clink rel=\"preload\"\u003e`. For more information check out [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content) or the [Google Developer Blog](https://developers.google.com/web/updates/2016/03/link-rel-preload).\n\n#### Props\n\n- `href: string`\n- `as: string` - resource type\n\n```js\nimport React from 'react';\nimport { Preload, Script } from 'the-platform';\n\nfunction App() {\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003ePreload\u003c/h1\u003e\n      \u003cReact.Suspense maxDuration={300} fallback={'loading...'}\u003e\n        \u003cPreload href=\"https://js.stripe.com/v3/\" rel=\"preload\" as=\"script\" /\u003e\n        \u003cScript src=\"https://js.stripe.com/v3/\" async /\u003e\n      \u003c/React.Suspense\u003e\n    \u003c/div\u003e\n  );\n}\n\nexport default App;\n```\n\n### `\u003cStylesheet\u003e`\n\nLazy load a stylesheet.\n\n#### Props\n\n- `href: string`\n\n```js\nimport React from 'react';\nimport { Stylesheet } from 'the-platform';\n\nfunction App() {\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eStyles\u003c/h1\u003e\n      \u003cReact.Suspense maxDuration={300} fallback={'loading...'}\u003e\n        \u003cStylesheet href=\"style.css\" /\u003e\n      \u003c/React.Suspense\u003e\n    \u003c/div\u003e\n  );\n}\n\nexport default App;\n```\n\n## Authors\n\n- [Jared Palmer](https://twitter.com/jaredpalmer)\n- [Jack Cross](https://twitter.com/crosscompile)\n- [Nathan Force](https://twitter.com/forcetheissue)\n\n## Inspiration\n\n- [react-fns](https://github.com/jaredpalmer/react-fns)\n- AOL.\n\n---\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaredpalmer%2Fthe-platform","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaredpalmer%2Fthe-platform","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaredpalmer%2Fthe-platform/lists"}