|
| 1 | +# React Native Directory API |
| 2 | + |
| 3 | +This document describes the server-side JSON API exposed by the React Native Directory. |
| 4 | + |
| 5 | +## Summary of available endpoints |
| 6 | + |
| 7 | +- [`GET /api/libraries`](#get-apilibraries) - list and search libraries (paginated, sorted, filterable) |
| 8 | +- [`POST /api/libraries/check`](#post-apilibrariescheck) - return metadata for a list of npm package names |
| 9 | +- [`GET /api/libraries/statistic`](#get-apilibrariesstatistic) - aggregated statistics about the directory dataset |
| 10 | +- [`GET /api/library`](#get-apilibrary) - lookup one or more libraries by npm package name (optionally `check` existence only) |
| 11 | +- [`GET /api/proxy/npm-stat`](#get-apiproxynpm-stat) - proxy to https://npm-stat.com download counts API |
| 12 | + |
| 13 | +## GET /api/libraries |
| 14 | + |
| 15 | +Return a list of libraries from the dataset. Supports sorting, full-text search, pagination and many filters. |
| 16 | + |
| 17 | +- Method: GET |
| 18 | +- Path: `/api/libraries` |
| 19 | +- Query parameters, all optional. The possible query parameters represents [`Query` type](https://github.com/react-native-community/directory/blob/main/types/index.ts#L22-L59): |
| 20 | + - `order` - sort key (available sorting keys: `updated`, `added`, `quality`, `popularity`, `downloads`, `issues`, `stars`, `relevance`, `size`, `dependencies`, `released`). |
| 21 | + - `direction` - `ascending` or `descending` (default: `descending`). |
| 22 | + - `search` - full-text search string (`relevance` sorting is used automatically when searching). |
| 23 | + - `owner` - filter by owner name. |
| 24 | + - `topic` - filter by topic or tag. |
| 25 | + - Platform support filters (booleans): `ios`, `android`, `web`, `windows`, `macos`, `expoGo`, `fireos`, `horizon`, `tvos`, `visionos`, `vegaos`. |
| 26 | + - Feature filters (booleans): `hasExample`, `hasImage`, `hasTypes`, `hasNativeCode`, `configPlugin`. |
| 27 | + - Quality filters (booleans): `isMaintained`, `isPopular`, `wasRecentlyUpdated`. |
| 28 | + - Architecture filters (booleans): `newArchitecture`, `expoModule`, `nitroModule`, `turboModule`. |
| 29 | + - Skip categories (booleans): `skipLibs`, `skipTools`, `skipTemplates`. |
| 30 | + - Numeric filters: `minPopularity`, `minMonthlyDownloads`. |
| 31 | + - `nightlyProgram` - boolean flag for Nightly Program participation. |
| 32 | + - `bookmarks` - when set, the server reads browser cookie bookmarks and returns only bookmarked libraries (see Notes below). |
| 33 | + - Pagination: `offset` (number, default `0`), `limit` (number, default `20`). |
| 34 | + |
| 35 | +### Notes |
| 36 | + |
| 37 | +- If `search` is provided and `order` is missing or equal to `relevance`, libraries are re-ranked by relevance. |
| 38 | +- If `bookmarks` is set, the server uses the cookie stored bookmarks (from `req.headers.cookie`) to filter. Responses with `bookmarks` set are not cached publicly. |
| 39 | + |
| 40 | +### Example |
| 41 | + |
| 42 | +- GET `/api/libraries?search=image&order=downloads&direction=descending&limit=1` |
| 43 | + |
| 44 | + Response: |
| 45 | + |
| 46 | + ```json |
| 47 | + { |
| 48 | + "libraries": [ |
| 49 | + { |
| 50 | + "githubUrl": "https://github.com/expo/expo/tree/main/packages/expo-image", |
| 51 | + "examples": ["https://docs.expo.dev/versions/latest/sdk/image/#usage"], |
| 52 | + "ios": true, |
| 53 | + "android": true, |
| 54 | + "web": true, |
| 55 | + "tvos": true, |
| 56 | + "expoGo": true, |
| 57 | + "fireos": true, |
| 58 | + "vegaos": "@amazon-devices/expo-image", |
| 59 | + "newArchitecture": true, |
| 60 | + "github": { |
| 61 | + "urls": { |
| 62 | + "repo": "https://github.com/expo/expo", |
| 63 | + "homepage": "https://docs.expo.dev/versions/latest/sdk/image/" |
| 64 | + }, |
| 65 | + "stats": { |
| 66 | + "hasIssues": true, |
| 67 | + "hasWiki": true, |
| 68 | + "hasSponsorships": false, |
| 69 | + "hasDiscussions": true, |
| 70 | + "hasProjects": false, |
| 71 | + "hasVulnerabilityAlerts": true, |
| 72 | + "hasTopics": false, |
| 73 | + "updatedAt": "2026-01-27T20:02:58Z", |
| 74 | + "createdAt": "2016-08-15T17:14:25Z", |
| 75 | + "pushedAt": "2026-01-27T20:02:58Z", |
| 76 | + "forks": 10924, |
| 77 | + "issues": 335, |
| 78 | + "subscribers": 351, |
| 79 | + "stars": 47312, |
| 80 | + "dependencies": 1 |
| 81 | + }, |
| 82 | + "name": "expo-image", |
| 83 | + "fullName": "expo/expo", |
| 84 | + "isPrivate": false, |
| 85 | + "description": "A cross-platform, performant image component for React Native and Expo with Web support", |
| 86 | + "topics": [], |
| 87 | + "license": { |
| 88 | + "name": "MIT License", |
| 89 | + "url": "http://choosealicense.com/licenses/mit/", |
| 90 | + "id": "MDc6TGljZW5zZTEz", |
| 91 | + "key": "mit", |
| 92 | + "spdxId": "MIT" |
| 93 | + }, |
| 94 | + "hasTypes": true, |
| 95 | + "newArchitecture": false, |
| 96 | + "isArchived": false, |
| 97 | + "hasReadme": true, |
| 98 | + "hasNativeCode": true, |
| 99 | + "configPlugin": true, |
| 100 | + "moduleType": "expo" |
| 101 | + }, |
| 102 | + "npmPkg": "expo-image", |
| 103 | + "npm": { |
| 104 | + "downloads": 5883973, |
| 105 | + "weekDownloads": 1011061, |
| 106 | + "size": 839777, |
| 107 | + "versionsCount": 226, |
| 108 | + "latestRelease": "3.0.11", |
| 109 | + "latestReleaseDate": "2025-12-05T06:50:48.709Z", |
| 110 | + "hasReadme": true |
| 111 | + }, |
| 112 | + "score": 90, |
| 113 | + "matchingScoreModifiers": [ |
| 114 | + "Very popular", |
| 115 | + "Popular", |
| 116 | + "Known", |
| 117 | + "Recently updated", |
| 118 | + "Has a README file", |
| 119 | + "Has a description", |
| 120 | + "Has vulnerability alerts enabled", |
| 121 | + "Lots of open issues" |
| 122 | + ], |
| 123 | + "popularity": 0.146, |
| 124 | + "topicSearchString": "", |
| 125 | + "matchScore": 425 |
| 126 | + } |
| 127 | + ], |
| 128 | + "total": 142 |
| 129 | + } |
| 130 | + ``` |
| 131 | + |
| 132 | +--- |
| 133 | + |
| 134 | +## POST /api/libraries/check |
| 135 | + |
| 136 | +Return compatibility metadata for a list of npm package names. This endpoint accepts a JSON body with an array of package names and responds with metadata for each package. |
| 137 | + |
| 138 | +- Method: POST |
| 139 | +- Path: `/api/libraries/check` |
| 140 | +- Body parameters: |
| 141 | + - `packages` - array of npm package names (required). |
| 142 | + |
| 143 | +### Notes |
| 144 | + |
| 145 | +- The request body must be a valid JSON object with a `packages` field. |
| 146 | +- The response includes metadata for each requested package, such as version, description, and repository URL. |
| 147 | + |
| 148 | +### Example |
| 149 | + |
| 150 | +- POST `/api/libraries/check` with body `{ "packages": ["react-native-reanimated"] }` |
| 151 | + |
| 152 | + Response: |
| 153 | + |
| 154 | + ```json |
| 155 | + { |
| 156 | + "react-native-reanimated": { |
| 157 | + "newArchitecture": "supported" |
| 158 | + } |
| 159 | + } |
| 160 | + ``` |
| 161 | + |
| 162 | +--- |
| 163 | + |
| 164 | +## GET /api/libraries/statistic |
| 165 | + |
| 166 | +Return aggregated statistics about the library dataset, such as total counts of libraries, downloads, and other metrics. |
| 167 | + |
| 168 | +- Method: GET |
| 169 | +- Path: `/api/libraries/statistic` |
| 170 | + |
| 171 | +### Example |
| 172 | + |
| 173 | +- GET `/api/libraries/statistic` |
| 174 | + |
| 175 | + Response: |
| 176 | + |
| 177 | + ```json |
| 178 | + { |
| 179 | + "total": 2326, |
| 180 | + "newArchitecture": 1570, |
| 181 | + "downloads": 7380762848, |
| 182 | + "weekDownloads": 1391864468, |
| 183 | + "unmaintained": 797, |
| 184 | + "withTypes": 1626, |
| 185 | + "withNativeCode": 1123, |
| 186 | + "withConfigPlugin": 243, |
| 187 | + "ios": 2199, |
| 188 | + "android": 2188, |
| 189 | + "web": 506, |
| 190 | + "expoGo": 972, |
| 191 | + "windows": 67, |
| 192 | + "macos": 44, |
| 193 | + "fireos": 216, |
| 194 | + "horizon": 3, |
| 195 | + "tvos": 100, |
| 196 | + "visionos": 32, |
| 197 | + "vegaos": 55 |
| 198 | + } |
| 199 | + ``` |
| 200 | + |
| 201 | +--- |
| 202 | + |
| 203 | +## GET /api/library |
| 204 | + |
| 205 | +Lookup one or more libraries by npm package name. Endpoint can optionally perform a quick `check` to return existence flag only. |
| 206 | + |
| 207 | +- Method: GET |
| 208 | +- Path: `/api/library` |
| 209 | +- Query parameters: |
| 210 | + - `name` - npm package name (required). |
| 211 | + - `check` - boolean flag to return existence information only, without full library data. |
| 212 | + |
| 213 | +### Notes |
| 214 | + |
| 215 | +- If `check` is `true`, the response includes only information about existence for the specified package(s). |
| 216 | +- If `check` is `false` or not provided, the response includes full library data. |
| 217 | + |
| 218 | +### Example |
| 219 | + |
| 220 | +- GET `/api/library?name=uniwind` |
| 221 | + |
| 222 | + Response: |
| 223 | + |
| 224 | + ```json |
| 225 | + { |
| 226 | + "uniwind": { |
| 227 | + "githubUrl": "https://github.com/uni-stack/uniwind/tree/main/packages/uniwind", |
| 228 | + "examples": [ |
| 229 | + "https://github.com/uni-stack/uniwind/tree/main/apps/expo-router", |
| 230 | + "https://github.com/uni-stack/uniwind/tree/main/apps/expo-example", |
| 231 | + "https://github.com/uni-stack/uniwind/tree/main/apps/bare" |
| 232 | + ], |
| 233 | + "ios": true, |
| 234 | + "android": true, |
| 235 | + "web": true, |
| 236 | + "expoGo": true, |
| 237 | + "newArchitecture": true, |
| 238 | + "github": { |
| 239 | + "urls": { |
| 240 | + "repo": "https://github.com/uni-stack/uniwind", |
| 241 | + "homepage": "https://uniwind.dev" |
| 242 | + }, |
| 243 | + "stats": { |
| 244 | + "hasIssues": true, |
| 245 | + "hasWiki": false, |
| 246 | + "hasSponsorships": false, |
| 247 | + "hasDiscussions": true, |
| 248 | + "hasProjects": true, |
| 249 | + "hasVulnerabilityAlerts": true, |
| 250 | + "hasTopics": true, |
| 251 | + "updatedAt": "2026-02-16T06:41:45Z", |
| 252 | + "createdAt": "2025-07-29T08:10:42Z", |
| 253 | + "pushedAt": "2026-02-16T06:41:45Z", |
| 254 | + "forks": 25, |
| 255 | + "issues": 2, |
| 256 | + "subscribers": 6, |
| 257 | + "stars": 1323, |
| 258 | + "dependencies": 4 |
| 259 | + }, |
| 260 | + "name": "uniwind", |
| 261 | + "fullName": "uni-stack/uniwind", |
| 262 | + "isPrivate": false, |
| 263 | + "description": "The fastest Tailwind bindings for React Native", |
| 264 | + "topics": ["unistyles", "tailwind", "tailwindcss", "theme", "style"], |
| 265 | + "license": { |
| 266 | + "name": "MIT License", |
| 267 | + "url": "http://choosealicense.com/licenses/mit/", |
| 268 | + "id": "MDc6TGljZW5zZTEz", |
| 269 | + "key": "mit", |
| 270 | + "spdxId": "MIT" |
| 271 | + }, |
| 272 | + "hasTypes": false, |
| 273 | + "newArchitecture": false, |
| 274 | + "isArchived": false, |
| 275 | + "hasReadme": true, |
| 276 | + "hasNativeCode": false, |
| 277 | + "configPlugin": false |
| 278 | + }, |
| 279 | + "npmPkg": "uniwind", |
| 280 | + "npm": { |
| 281 | + "downloads": 196697, |
| 282 | + "weekDownloads": 28489, |
| 283 | + "size": 635831, |
| 284 | + "versionsCount": 42, |
| 285 | + "latestRelease": "1.3.1", |
| 286 | + "latestReleaseDate": "2026-02-13T10:35:54.904Z", |
| 287 | + "hasReadme": true |
| 288 | + }, |
| 289 | + "score": 60, |
| 290 | + "matchingScoreModifiers": [ |
| 291 | + "Popular", |
| 292 | + "Known", |
| 293 | + "Recently updated", |
| 294 | + "Has a README file", |
| 295 | + "Has a description", |
| 296 | + "Has vulnerability alerts enabled" |
| 297 | + ], |
| 298 | + "popularity": 0.123, |
| 299 | + "topicSearchString": "unistyles tailwind tailwindcss theme style" |
| 300 | + } |
| 301 | + } |
| 302 | + ``` |
| 303 | + |
| 304 | +- GET `/api/library?name=react&check=true` |
| 305 | + |
| 306 | + Response: |
| 307 | + |
| 308 | + ```json |
| 309 | + { |
| 310 | + "uniwind": true |
| 311 | + } |
| 312 | + ``` |
| 313 | + |
| 314 | +--- |
| 315 | + |
| 316 | +## GET /api/proxy/npm-stat |
| 317 | + |
| 318 | +Proxy to npm-stat.com to fetch download counts for the last month. This endpoint is a simple proxy and does not perform any data processing. |
| 319 | + |
| 320 | +- Method: GET |
| 321 | +- Path: `/api/proxy/npm-stat` |
| 322 | +- Query parameters: |
| 323 | + - `name` - npm package name (required). |
| 324 | + |
| 325 | +### Notes |
| 326 | + |
| 327 | +- It is subject to the same CORS and rate limiting policies as the original npm-stat.com. |
| 328 | + |
| 329 | +### Example |
| 330 | + |
| 331 | +- GET `/api/proxy/npm-stat?name=react` |
| 332 | + |
| 333 | + Response: |
| 334 | + |
| 335 | + ```json |
| 336 | + { |
| 337 | + "react-native": { |
| 338 | + "2026-01-18": 319495, |
| 339 | + "2026-01-19": 693157, |
| 340 | + "2026-01-20": 810833, |
| 341 | + "2026-01-21": 837204, |
| 342 | + "2026-01-22": 845437, |
| 343 | + "2026-01-23": 777158, |
| 344 | + "2026-01-24": 378434, |
| 345 | + "2026-01-25": 339869, |
| 346 | + "2026-01-26": 813923, |
| 347 | + "2026-01-27": 888545, |
| 348 | + "2026-01-28": 877008, |
| 349 | + "2026-01-29": 880932, |
| 350 | + "2026-01-30": 855686, |
| 351 | + "2026-01-31": 390039, |
| 352 | + "2026-02-01": 380828, |
| 353 | + "2026-02-02": 853673, |
| 354 | + "2026-02-03": 898431, |
| 355 | + "2026-02-04": 911421, |
| 356 | + "2026-02-05": 935844, |
| 357 | + "2026-02-06": 879993, |
| 358 | + "2026-02-07": 417938, |
| 359 | + "2026-02-08": 403069, |
| 360 | + "2026-02-09": 891276, |
| 361 | + "2026-02-10": 969193, |
| 362 | + "2026-02-11": 942355, |
| 363 | + "2026-02-12": 939358, |
| 364 | + "2026-02-13": 834084, |
| 365 | + "2026-02-14": 390313, |
| 366 | + "2026-02-15": 403198, |
| 367 | + "2026-02-16": 771778 |
| 368 | + } |
| 369 | + } |
| 370 | + ``` |
0 commit comments