{"id":50958396,"url":"https://github.com/gee1k/expo-udp","last_synced_at":"2026-06-18T10:30:39.916Z","repository":{"id":365257425,"uuid":"1271243096","full_name":"gee1k/expo-udp","owner":"gee1k","description":"Modern UDP sockets for Expo on iOS and Android","archived":false,"fork":false,"pushed_at":"2026-06-16T14:56:20.000Z","size":649,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-16T16:10:17.889Z","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/gee1k.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,"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-06-16T13:23:51.000Z","updated_at":"2026-06-16T14:58:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gee1k/expo-udp","commit_stats":null,"previous_names":["gee1k/expo-udp"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/gee1k/expo-udp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gee1k%2Fexpo-udp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gee1k%2Fexpo-udp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gee1k%2Fexpo-udp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gee1k%2Fexpo-udp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gee1k","download_url":"https://codeload.github.com/gee1k/expo-udp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gee1k%2Fexpo-udp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34487069,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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-06-18T10:30:38.998Z","updated_at":"2026-06-18T10:30:39.908Z","avatar_url":"https://github.com/gee1k.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @isvend/expo-udp\n\nA modern Expo native module for low-level UDP sockets on iOS and Android.\n\n`@isvend/expo-udp` provides a small Promise-based socket API for unicast,\nbroadcast, multicast, IPv4, IPv6, and common UDP socket options. It also\nexports a thin `useUdpSocket` hook for screen-local lifecycle management.\n\n## Features\n\n- Expo Modules API native implementation for iOS and Android.\n- UDP4 and UDP6 sockets.\n- Bind, send, receive, close, and local address lookup.\n- Broadcast and multicast controls.\n- Stable socket-level events: `message`, `error`, `listening`, and `close`.\n- A small React hook for automatically creating, binding, and closing a socket\n  inside a single screen or component.\n\n## Installation\n\n```sh\nnpx expo install @isvend/expo-udp\n```\n\nAdd the config plugin to your app config:\n\n```json\n{\n  \"expo\": {\n    \"plugins\": [\n      [\n        \"@isvend/expo-udp\",\n        {\n          \"localNetworkUsageDescription\": \"This app uses the local network to discover and communicate with devices.\",\n          \"multicast\": true\n        }\n      ]\n    ]\n  }\n}\n```\n\n`multicast` is optional. Enable it only when your app joins multicast groups.\n\n## Raw Socket API\n\n```ts\nimport { createSocket } from '@isvend/expo-udp';\n\nconst socket = await createSocket({ type: 'udp4', reuseAddress: true });\n\nawait socket.bind({ port: 12345, address: '0.0.0.0' });\n\nconst subscription = socket.addListener('message', (event) =\u003e {\n  console.log(event.remoteAddress, event.remotePort, event.data);\n});\n\nawait socket.send('hello', { host: '127.0.0.1', port: 12345 });\n\nsubscription.remove();\nawait socket.close();\n```\n\nBroadcast:\n\n```ts\nawait socket.setBroadcast(true);\nawait socket.send('hello', { host: '255.255.255.255', port: 9999 });\n```\n\nMulticast:\n\n```ts\nawait socket.bind({ port: 5353, address: '0.0.0.0' });\nawait socket.joinMulticastGroup('224.0.0.251');\nawait socket.setMulticastTTL(1);\n```\n\n## React Hook\n\n`useUdpSocket` is a lifecycle helper for a single screen or component. It does\nnot share sockets globally, parse messages, route channels, reconnect, or own\napp-level UDP services.\n\n```ts\nimport { useUdpSocket } from '@isvend/expo-udp';\n\nconst { status, error, localAddress, send, close } = useUdpSocket({\n  socket: { type: 'udp4', reuseAddress: true },\n  bind: { port: 12345, address: '0.0.0.0' },\n  onMessage(event) {\n    console.log(event.data);\n  },\n});\n```\n\nPass `autoBind: false` when you want to create the socket immediately but bind\nit from a button or another user action:\n\n```ts\nconst { bind, close } = useUdpSocket({\n  autoBind: false,\n  socket: { type: 'udp4', reuseAddress: true },\n  bind: { port: 12345, address: '0.0.0.0' },\n});\n\nawait bind();\nawait close();\n```\n\n## API\n\n- `createSocket(options?)`\n- `socket.bind(options?)`\n- `socket.send(data, remote)`\n- `socket.close()`\n- `socket.address()`\n- `socket.setBroadcast(enabled)`\n- `socket.joinMulticastGroup(group, iface?)`\n- `socket.leaveMulticastGroup(group, iface?)`\n- `socket.setMulticastTTL(ttl)`\n- `socket.setMulticastLoopback(enabled)`\n- `socket.addListener('message' | 'error' | 'listening' | 'close', listener)`\n- `useUdpSocket(options)`\n\n## Types\n\n```ts\ntype UdpSocketType = 'udp4' | 'udp6';\ntype UdpPayload = Uint8Array | ArrayBuffer | string;\n\ntype SocketAddress = {\n  address: string;\n  port: number;\n  family: UdpSocketType;\n};\n\ntype MessageEvent = {\n  data: Uint8Array;\n  remoteAddress: string;\n  remotePort: number;\n  family: UdpSocketType;\n};\n```\n\nBinding to `0.0.0.0` or `::` means listening on all interfaces for that address\nfamily. Bind to `127.0.0.1` or `::1` when you only want loopback traffic.\n\n## Platform Notes\n\n- iOS requires a local network usage description for local network traffic.\n- iOS multicast may require Apple's multicast networking entitlement for App\n  Store distribution.\n- Android always needs `android.permission.INTERNET`.\n- Android multicast over Wi-Fi may require\n  `android.permission.CHANGE_WIFI_MULTICAST_STATE`; the config plugin adds it\n  when `multicast: true`.\n- Simulator and emulator networking differs from real devices, especially for\n  broadcast and multicast. Validate those flows on hardware.\n\n## Validation Status\n\nUnicast, bind, send, receive, close, and close-then-rebind flows have been\nexercised in the example app. Broadcast and multicast are implemented but should\nbe validated on the target physical networks and devices you plan to support.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgee1k%2Fexpo-udp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgee1k%2Fexpo-udp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgee1k%2Fexpo-udp/lists"}